Как преобразовать макрос в массив как #define a_macro {5,7,7,97}?
Пожалуйста, пройдите.
#define _VERSION_ 1.4
#define DEFAULT_NETWORK_TOKEN_KEY { 3, 6, 5, 100}
// Я не могу изменить вышеупомянутые макросы, но ниже
#define STR_VALUE(arg) #arg
#define FUNCTION_NAME(name) STR_VALUE(name\r)
#define TEST_FUNC #AP started v _VERSION_
#define TEST_FUNC_NAME FUNCTION_NAME(TEST_FUNC)
#define QUOTE_X(t)#t
#define QUOTE(t)QUOTE_X(t)
#define ABC 100 //{ 3, 6, 5, 100}
#define MYSTR "The value of ABC is"
const uint8 startMsg[] = MYSTR " " QUOTE(ABC);
Результаты: значение ABC составляет 100
const uint8 startMsg[] = TEST_FUNC_NAME;
Результаты: #AP начал v 1.4 (возврат каретки) // Я также хочу удалить пробел между v и 1.4
я хочу
const uint8 startMsg[] = ?? ;
Если результат #AP начался [3.6.5.100] v1.4 (возврат каретки) или #AP начался [3,6,5,100] v1.4 (возврат каретки) или аналогичный.
Я работаю над чипом SOC и должен показать это при запуске. Срочный.:)
------ Ответ на вопрос ------
#define NETTOKENKEY(a,b,c,d) "[" #a "." #b "." #c "." #d "]"
#define GENNETTOKENKEY(z) NETTOKENKEY(z)
#define STRINGIZER(arg) #arg
#define STR_VALUE(arg) STRINGIZER(arg)
#define AP_VERSION_STR "#AP started v" STR_VALUE(_VERSION_)
#define AP_NETVERSION_STR "#AP started " \
GENNETTOKENKEY(DEFAULT_NETWORK_TOKEN_KEY_VALUES) \
" v" STR_VALUE(_VERSION_) **"\r"**
const uint8 startMsg[] = AP_NETVERSION_STR ;
4 ответа
Препроцессор C - довольно простая программа для подстановки текста, и я не думаю, что она сможет делать то, что вам нужно, и создавать константы во время компиляции, если абсолютно невозможно изменить DEFAULT_NETWORK_TOKEN_KEY
макро.
Преобразование нотации 'массива' особенно сложно - фактически, предварительное условие не изменять макрос, определяющий массив, вероятно, означает, что это невозможно.
Если возможно определить новые макросы и переопределить DEFAULT_NETWORK_TOKEN_KEY
так что он производит то же значение, что и всегда, тогда вы можете получить желаемый результат.
Для иллюстрации обратите внимание, что вы можете написать:
#define x { 3, 45, 5, 49}
#define f4(a,b,c,d) #a " - " #b ":" #c "/" #d
#define y(z) f4(z)
y(x)
При предварительной обработке получается:
"{ 3" " - " "45" ":" "5" "/" "49}"
Обратите внимание, что фигурные скобки являются частями аргументных строк. Теперь, если вы можете сделать:
#define DEFAULT_NETWORK_TOKEN_KEY_VALUES 3, 6, 5, 100
#define DEFAULT_NETWORK_TOKEN_KEY { DEFAULT_NETWORK_TOKEN_KEY_VALUES}
(где я сохраняю ваш асимметричный интервал, хотя я не думаю, что это действительно необходимо), тогда вы можете использовать:
#define NETTOKENKEY(a,b,c,d) "[" #a "." #b "." #c "." #d "]"
#define GENNETTOKENKEY(z) NETTOKENKEY(z)
GENNETTOKENKEY(DEFAULT_NETWORK_TOKEN_KEY_VALUES)
чтобы получить строку "[3.6.5.100]" (для значений в моем примере).
Избавление от пространства между v
и 1.4
относительно легко:
#define STRINGIZER(arg) #arg
#define STR_VALUE(arg) STRINGIZER(arg)
#define AP_VERSION_STR "#AP started v" STR_VALUE(_VERSION_)
AP_VERSION_STR
Соединение их вместе дает:
#define AP_NETVERSION_STR "#AP started " \
GENNETTOKENKEY(DEFAULT_NETWORK_TOKEN_KEY_VALUES) \
" v" STR_VALUE(_VERSION_)
static const char version[] = AP_NETVERSION_STR;
Если вы хотите '\r'
в конце добавить "\r"
до конца определения макроса AP_NETVERSION_STR. Конкатенация строк очень полезна!
Но это основано на способности "изменить" определение DEFAULT_NETWORK_TOKEN_KEY
так что его можно отформатировать так. Без этого изменения, я не думаю, что вы можете сделать это.
Тестирование необходимо!
#define _VERSION_ 1.4
#define DEFAULT_NETWORK_TOKEN_KEY_VALUES 3, 6, 5, 100
#define DEFAULT_NETWORK_TOKEN_KEY { DEFAULT_NETWORK_TOKEN_KEY_VALUES}
#define NETTOKENKEY(a,b,c,d) "[" #a "." #b "." #c "." #d "]"
#define GENNETTOKENKEY(z) NETTOKENKEY(z)
GENNETTOKENKEY(DEFAULT_NETWORK_TOKEN_KEY_VALUES)
#define STRINGIZER(arg) #arg
#define STR_VALUE(arg) STRINGIZER(arg)
#define AP_VERSION_STR "#AP started v" STR_VALUE(_VERSION_)
AP_VERSION_STR
#define AP_NETVERSION_STR "#AP started " \
GENNETTOKENKEY(DEFAULT_NETWORK_TOKEN_KEY_VALUES) \
" v" STR_VALUE(_VERSION_)
AP_NETVERSION_STR
Когда пробежишь gcc -E
Дезинфицированный вывод (пустые строки и #line
убраны элементы управления) вот что нам нужно:
"[" "3" "." "6" "." "5" "." "100" "]"
"#AP started v" "1.4"
"#AP started " "[" "3" "." "6" "." "5" "." "100" "]" " v" "1.4"
Вам лучше использовать структуру данных препроцессора, предоставленную Boost.Preprocessor. Все макросы там работают в стандартном C89.
Зачем использовать макрос, если вы можете:
uint arr[] = DEFAULT_NETWORK_TOKEN_KEY;
float v = VERSION;
sprintf(buffer, "#AP started [%u.%u.%u.%u] v%f", arr[0], arr[1], arr[2], arr[3], v);
Читайте о # и ## в препроцессоре C. Вы кладете много обертки вокруг чего-то довольно легко
http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
Кстати, AFAIK, вы не сможете использовать препроцессор, чтобы превратить ваш {} в []