Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何将具有数组的宏字符串化为#定义一个_宏{5,7,97}?_C_Macros_Embedded - Fatal编程技术网

C 如何将具有数组的宏字符串化为#定义一个_宏{5,7,97}?

C 如何将具有数组的宏字符串化为#定义一个_宏{5,7,97}?,c,macros,embedded,C,Macros,Embedded,请通过 #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 FUNCTI

请通过

#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启动了v1.4(回车)//我还想删除v和1.4之间的空格

我想要

const uint8 startMsg[] = ?? ;
结果应为#AP启动[3.6.5.100]v1.4(回车)或#AP启动[3,6,5100]v1.4(回车)或类似结果

我在一个SOC芯片上工作,需要在启动时展示这一点。紧急的 :)

------这个问题的答案是------


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

您最好使用由提供的预处理器数据结构。那里的所有宏都在标准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); 

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

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预处理器中的#和##的内容。你在很简单的事情上加了很多包装

顺便说一句,恐怕你无法使用预处理器将{}转换为[]

阅读有关C预处理器中的#和##的内容。你在很简单的事情上加了很多包装


顺便说一句,如果您不能使用预处理器将{}转换为[]

C预处理器是一个相当简单的文本替换程序,我认为如果绝对不可能更改
DEFAULT\u NETWORK\u TOKEN\u KEY
宏,那么它将无法执行您需要的操作并生成编译时常量字符串

转换“数组”表示法特别困难-事实上,不更改数组定义宏的前提条件可能意味着这是不可能的

如果可以定义新的宏并重新定义
DEFAULT\u NETWORK\u TOKEN\u 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\u NETVERSION\u STR宏定义的末尾。字符串连接非常有用

但是,这取决于是否能够“更改”默认网络令牌密钥的定义,从而使其符合如下格式。如果没有这个改变,我认为你做不到


测试是必要的

#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
运行时,轻度消毒的输出(删除空行和
#行
控件)是我们需要的:

"[" "3" "." "6" "." "5" "." "100" "]"

"#AP started v" "1.4"

"#AP started " "[" "3" "." "6" "." "5" "." "100" "]" " v" "1.4"

C预处理器是一个相当简单的文本替换程序,如果绝对不可能更改
DEFAULT\u NETWORK\u TOKEN\u KEY
宏,我认为它将无法满足您的需要并生成编译时常量字符串

转换“数组”表示法特别困难-事实上,不更改数组定义宏的前提条件可能意味着这是不可能的

如果可以定义新的宏并重新定义
DEFAULT\u NETWORK\u TOKEN\u 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\u NETVERSION\u STR宏定义的末尾。字符串连接非常有用

但是,这取决于是否能够“更改”默认网络令牌密钥的定义,从而使其符合如下格式。如果没有这个改变,我认为你做不到


测试是必要的

#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
运行时,轻度消毒的输出(删除空行和
#行
控件)是我们需要的:

"[" "3" "." "6" "." "5" "." "100" "]"

"#AP started v" "1.4"

"#AP started " "[" "3" "." "6" "." "5" "." "100" "]" " v" "1.4"

我现在不能做。预处理器对于我的4K内存板来说太大了。你没有在4K内存板上运行C预处理器;您正在开发机器上运行它。输出被下载到你的电路板上,或者烧录到EEPROM中,或者别的什么。我必须生成一个十六进制文件并下载到芯片的闪存中。编译前先运行预处理器,输出就可以了,Boist.PP只是一堆宏。我现在不能做。预处理器对于我的4K内存板来说太大了。你没有在4K内存板上运行C预处理器;您正在开发机器上运行它。输出被下载到你的电路板上,或者烧录到EEPROM中,或者其他任何东西。我必须生成一个十六进制文件并将其下载到芯片的闪存中。编译前运行预处理器,输出就可以了,Boist.PP只是一堆宏。如果只是在运行时打印数据,这是最好的解决方案。(如果OP需要它作为编译对象中的常量字符串,则需要另一种解决方案)如果它是一个具有4KB RAM的硬件(请参阅对Joel Falcou答案的评论),
sprintf()
可能不是一个选项。我不想使用sprintf。对我来说很重。但是f