将预处理器令牌转换为字符串


70

我正在寻找一种将预处理器令牌转换为字符串的方法。

具体来说,我在某处:

我想用它来防止缓冲区溢出:

我愿意采用其他方式来完成同一件事,但仅限于标准库。



Answers:


112

具体参见http://www.decompile.com/cpp/faq/file_and_line_error_string.htm

所以你的问题可以通过解决 sscanf(buf, "%" TOSTRING(MAX_LEN) "s", val);


3
为什么级联2个宏?会不会足够一个?
feedc0de

请参阅以下有关双扩展字符串化的答案。C / C ++预处理器肮脏且丑陋,我相信没有标准。那么为什么我需要说两个而不是一个呢,因为我不想做研究。
丹·丹

13
@Daniel Brunner单个宏将粘贴令牌本身,从字面上"%" "MAX_LEN" "%"产生第二个宏会导致令牌被粘贴,例如,"16"因为该TOSTRING宏使最终代码等效于STRINGIFY(16)
蒂姆·西尔维斯特

@TimSylvester我希望我能为您提供评论!:)
Matthieu

23

我在网上找到了答案。

上面的方法不起作用,但希望能说明我想做的事情,即使VERSION_STRING最终为“ v4.47”。

要生成适当的数字形式,请使用类似


7

已经有一段时间了,但这应该可行:

如果没有,则需要“双重扩展”技巧:


2
第一个无效;#在宏扩展中将宏参数字符串化。第二个将起作用。
乔纳森·勒夫勒

@RaviRaj —因为#仅将宏参数字符串化,并且第一行不在宏的主体中。
乔纳森·莱夫勒

3

您应该使用双扩展字符串化宏技巧。或者只是有一个

并保持同步。(这有点麻烦,但是只要定义彼此相邻,您就可能会记得。)

实际上,在这种情况下,还strncpy不够吗?

如果是printf,那会更容易:


1
是的,我希望*或其他符号可用于带有参数的长度限制scanf例程。那种形式的sprintf比imo的strncpy更好,因为如果strncpy溢出了缓冲区,strncpy不会终止该字符串,而当字符串太短时,它将写入额外的数据。
davenpcj

1

尽管上面的某些“工作”有效,但我个人还是建议仅使用简单的字符串API来代替libc中的dreck。有许多可移植的API,其中一些也进行了优化以方便您包含在项目中……还有一些类似ustr的空间开销很小,并且支持堆栈变量。


0

我的两分钱。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.