如何字符串化宏有数组的#define a_macro {5,7,7,97}? [英] How to stringify macro having array as #define a_macro {5,7,7,97}?

查看:510
本文介绍了如何字符串化宏有数组的#define a_macro {5,7,7,97}?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请去。

 的#define _VERSION_ 1.4
的#define DEFAULT_NETWORK_TOKEN_KEY {3,6,5,100}

//我不能改变上面的宏但低于

 的#define STR_VALUE(AR​​G)#arg
#定义FUNCTION_NAME(名)STR_VALUE(名称\\ R)
#定义TEST_FUNC #AP开始v _VERSION_
#定义TEST_FUNC_NAME FUNCTION_NAME(TEST_FUNC)#定义QUOTE_X(T)#T
#定义QUOTE(T)QUOTE_X(T)
#定义ABC 100 // {3,6,5,100}
#定义myStr的ABC的值为常量UINT8 startMsg [] = myStr的QUOTE(ABC);

结果: ABC的值是100

 常量UINT8 startMsg [] = TEST_FUNC_NAME;

结果: #AP启动1.4版(回车)//我也想删除V和1.4之间的空间

我想

 常量UINT8 startMsg [] =? ;

应该产生的 #AP开始[3.6.5.100] 1.4版(回车)或 #AP开始[3,6,5,100] V1.4 (回车返回)或类似的。

我工作的SOC芯片上,并需要在启动时显示此。紧急。
:)

------回答的问题是------

 的#define NETTOKENKEY(A,B,C,D)[#A。 #B。 #C 。 #天]
#定义GENNETTOKENKEY(Z)NETTOKENKEY(Z)#定义STRINGIZER(ARG)#arg
#定义STR_VALUE(AR​​G)STRINGIZER(ARG)
#定义AP_VERSION_STR#AP开始VSTR_VALUE(_VERSION_)#定义AP_NETVERSION_STR#AP开始\\
                            GENNETTOKENKEY(DEFAULT_NETWORK_TOKEN_KEY_VALUES)\\
                            VSTR_VALUE(_VERSION_)**为\\ r**常量UINT8 startMsg [] = AP_NETVERSION_STR;


解决方案

的C preprocessor是一个相当头脑简单的文本替换程序,我不认为这将是能够做你需要什么并产生编译时常量字符串的如果的是绝对不可能更改 DEFAULT_NETWORK_TOKEN_KEY 宏。

转化的阵列表示法是特别困难的。 - 事实上,在不改变阵列限定宏的precondition可能意味着不可能

如果有可能定义新的宏和重新定义 DEFAULT_NETWORK_TOKEN_KEY ,这样它产生,因为它总是做同样的价值,那么你就可以得到你想要的结果。

要说明,请注意,你可以写:

 的#define X {3,45,5,49}
#定义F4(A,B,C,D)#A - #B:#C/#D
#定义Y(z)的F4(Z)Y(X)

在pre-处理,产生:

 {3 - 45:5/49}

注意括号是参数字符串的一部分。现在,如果你可以这样做:

 的#define DEFAULT_NETWORK_TOKEN_KEY_VALUES 3,6,5,100
#定义DEFAULT_NETWORK_TOKEN_KEY {} DEFAULT_NETWORK_TOKEN_KEY_VALUES

(这里我是preserving的不对称间距,但我不认为这真的有必要),那么你可以使用:

 的#define NETTOKENKEY(A,B,C,D)[#A。 #B。 #C 。 #天]
#定义GENNETTOKENKEY(Z)NETTOKENKEY(Z)GENNETTOKENKEY(DEFAULT_NETWORK_TOKEN_KEY_VALUES)

要获得字符串[3.6.5.100](在我的例子中值)。

摆脱 v 1.4 是相对容易的之间的空间:

 的#define STRINGIZER(ARG)#arg
#定义STR_VALUE(AR​​G)STRINGIZER(ARG)
#定义AP_VERSION_STR#AP开始VSTR_VALUE(_VERSION_)AP_VERSION_STR

凑合这些结合在一起收益率:

 的#define AP_NETVERSION_STR#AP开始\\
                            GENNETTOKENKEY(DEFAULT_NETWORK_TOKEN_KEY_VALUES)\\
                            VSTR_VALUE(_VERSION_)静态常量字符版本[] = AP_NETVERSION_STR;

如果你想有一个'\\ r'的末尾添加为\\ r来的结束在AP_NETVERSION_STR宏定义。字符串连接是的非常的有用!

不过,这是pdicated上能够改变 DEFAULT_NETWORK_TOKEN_KEY 的定义$ P $,使其适合于被格式化这样。如果没有这些变化,我不认为你可以做到这一点。


测试是必要的!

 的#define _VERSION_ 1.4
的#define DEFAULT_NETWORK_TOKEN_KEY_VALUES 3,6,5,100
#定义DEFAULT_NETWORK_TOKEN_KEY {} DEFAULT_NETWORK_TOKEN_KEY_VALUES#定义NETTOKENKEY(A,B,C,D)[#A。 #B。 #C 。 #天]
#定义GENNETTOKENKEY(Z)NETTOKENKEY(Z)GENNETTOKENKEY(DEFAULT_NETWORK_TOKEN_KEY_VALUES)#定义STRINGIZER(ARG)#arg
#定义STR_VALUE(AR​​G)STRINGIZER(ARG)
#定义AP_VERSION_STR#AP开始VSTR_VALUE(_VERSION_)AP_VERSION_STR#定义AP_NETVERSION_STR#AP开始\\
                            GENNETTOKENKEY(DEFAULT_NETWORK_TOKEN_KEY_VALUES)\\
                            VSTR_VALUE(_VERSION_)AP_NETVERSION_STR

当通过的gcc -E 运行,轻度消毒输出(空行和#行控制去掉)是我们需要什么:

 [3。 6。 5。 100]#AP开始V1.4#AP开始[3。 6。 5。 100]V1.4

Please go through.

#define _VERSION_ 1.4
#define DEFAULT_NETWORK_TOKEN_KEY { 3, 6, 5, 100}

// I can't change the above macros but below

#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);

results: The value of ABC is 100

const uint8 startMsg[] =  TEST_FUNC_NAME;

results: #AP started v 1.4 (Carriage return) // I also want to remove the space between v and 1.4

I want

const uint8 startMsg[] = ?? ;

Should result #AP started [3.6.5.100] v1.4 (Carriage return) or #AP started [3,6,5,100] v1.4 (Carriage return) or similar.

I am working on an SOC chip and need to show this in the startup. Urgent. :)

------ Answer to the question is ------

#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 ;

解决方案

The C Preprocessor is a fairly simple-minded text substitution program, and I don't think it is going to be able to do what you need and produce compile-time constant strings if it is absolutely impossible to change the DEFAULT_NETWORK_TOKEN_KEY macro.

Transforming the 'array' notation is particularly difficult — in fact, the precondition of not changing the array defining macro probably means it is impossible.

If it is possible to define new macros and redefine DEFAULT_NETWORK_TOKEN_KEY so that it produces the same value as it always did, then you can get to the result you want.

To illustrate, note that you can write:

#define x             { 3, 45, 5, 49}
#define f4(a,b,c,d)   #a " - " #b ":" #c "/" #d
#define y(z)          f4(z)

y(x)

When pre-processed, that produces:

"{ 3" " - " "45" ":" "5" "/" "49}"

Note that the braces are parts of the argument strings. Now, if you can do:

#define DEFAULT_NETWORK_TOKEN_KEY_VALUES 3, 6, 5, 100
#define DEFAULT_NETWORK_TOKEN_KEY { DEFAULT_NETWORK_TOKEN_KEY_VALUES}

(where I'm preserving your asymmetric spacing, though I don't think that's really necessary), then you can use:

#define NETTOKENKEY(a,b,c,d)  "[" #a "." #b "." #c "." #d "]"
#define GENNETTOKENKEY(z)    NETTOKENKEY(z)

GENNETTOKENKEY(DEFAULT_NETWORK_TOKEN_KEY_VALUES)

to get the string "[3.6.5.100]" (for the values in my example).

Getting rid of the space between the v and the 1.4 is relatively easy:

#define STRINGIZER(arg)     #arg
#define STR_VALUE(arg)      STRINGIZER(arg)
#define AP_VERSION_STR      "#AP started v" STR_VALUE(_VERSION_)

AP_VERSION_STR

Piecing these together yields:

#define AP_NETVERSION_STR   "#AP started " \
                            GENNETTOKENKEY(DEFAULT_NETWORK_TOKEN_KEY_VALUES) \
                            " v" STR_VALUE(_VERSION_)

static const char version[] = AP_NETVERSION_STR;

If you want a '\r' on the end, add "\r" to the end of the AP_NETVERSION_STR macro definition. String concatenation is very useful!

But, this is predicated on being able to 'change' the definition of DEFAULT_NETWORK_TOKEN_KEY so that it is amenable to being formatted like this. Without that change, I don't think you can do it.


Testing is necessary!

#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

When run through gcc -E, the mildly sanitized output (blank lines and #line controls removed) is what we need:

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

"#AP started v" "1.4"

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

这篇关于如何字符串化宏有数组的#define a_macro {5,7,7,97}?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆