0

请通过。

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

results: #AP started v 1.4 (Carriage return) // 我也想去掉 v 和 1.4 之间的空格

我想

const uint8 startMsg[] = ?? ;

应该导致#AP started [3.6.5.100] v1.4(回车)或#AP started [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

4 回答 4

2

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

摆脱 thev和 the之间的空间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"
于 2012-07-27T15:04:23.473 回答
1

您最好使用Boost.Preprocessor提供的 Preprocessor Data 结构。那里的所有宏都在标准 C89 中工作。

于 2012-07-27T14:49:27.420 回答
1

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

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); 
于 2012-07-27T14:52:44.967 回答
1

阅读 C 预处理器中的 # 和 ##。你在一些很简单的东西上放了很多包装

http://gcc.gnu.org/onlinedocs/cpp/Stringification.html

顺便说一句,AFAIK 您将无法使用预处理器将您的 {} 变成 []

于 2012-07-27T14:59:28.497 回答