Как преобразовать макрос в массив как #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, вы не сможете использовать препроцессор, чтобы превратить ваш {} в []

Другие вопросы по тегам