如何将具有数组的宏字符串化为#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 ; 

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]”(对于我的示例中的值)。

摆脱v1.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" 

如果可以,为什么要使用宏:

 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

BTW,AFAIK你将无法使用预处理器将{}转换为[]

您最好使用Boost.Preprocessor提供的预处理器数据结构。 所有宏都在标准C89中工作。