我正在寻找将预处理器令牌转换为字符串的方法。将预处理器令牌转换为字符串
具体来说,我在什么地方了:
#define MAX_LEN 16
,我想用它来防止缓冲区溢出:
char val[MAX_LEN+1]; // room for \0
sscanf(buf, "%"MAX_LEN"s", val);
我打开其他的方法来完成同样的事情,但只有标准库。
我正在寻找将预处理器令牌转换为字符串的方法。将预处理器令牌转换为字符串
具体来说,我在什么地方了:
#define MAX_LEN 16
,我想用它来防止缓冲区溢出:
char val[MAX_LEN+1]; // room for \0
sscanf(buf, "%"MAX_LEN"s", val);
我打开其他的方法来完成同样的事情,但只有标准库。
看到http://www.decompile.com/cpp/faq/file_and_line_error_string.htm 明确:
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define AT __FILE__ ":" TOSTRING(__LINE__)
所以你的问题是可以解决这样做 sscanf(buf, "%" TOSTRING(MAX_LEN) "s", val);
为什么级联2个宏?不会是一个足够的TOSTRING? – 2017-10-05 12:52:11
我在网上找到了答案。
#define VERSION_MAJOR 4 #define VERSION_MINOR 47 #define VERSION_STRING "v" #VERSION_MAJOR "." #VERSION_MINOR
以上不工作,但希望 说明我想怎样做, 即让VERSION_STRING最终成为 “v4.47”。
生成适当的数字形式 使用类似
#define VERSION_MAJOR 4 #define VERSION_MINOR 47 #define STRINGIZE2(s) #s #define STRINGIZE(s) STRINGIZE2(s) #define VERSION_STRING "v" STRINGIZE(VERSION_MAJOR) \ "." STRINGIZE(VERSION_MINOR) #include <stdio.h> int main() { printf ("%s\n", VERSION_STRING); return 0; }
“STRINGIZE”听起来很糟糕.. – Blindy 2010-04-25 20:06:02
这已经有一段时间,但这应该工作:
sscanf(buf, "%" #MAX_LEN "s", val);
如果没有,就需要“双重扩张”把戏:
#define STR1(x) #x
#define STR(x) STR1(x)
sscanf(buf, "%" STR(MAX_LEN) "s", val);
第一个不行; #在宏扩展中对宏参数进行字符串化。第二个将起作用。 – 2008-10-27 15:55:14
您应该使用双膨胀字串宏伎俩。或者只是有一个
#define MAX_LEN 16
#define MAX_LEN_S "16"
char val[MAX_LEN+1];
sscanf(buf, "%"MAX_LEN_S"s", val);
并保持它的同步。 (这有点麻烦,但只要定义彼此相邻,你可能会记得。)
其实,在这种特殊情况下,不会有strncpy
就够了吗?
strncpy(val, buf, MAX_LEN);
val[MAX_LEN] = '\0';
如果是printf
,不过,这将是更容易:
sprintf(buf, "%.*s", MAX_LEN, val);
虽然上述一些“工作”,我个人倒只用一个简单的字符串API,而不是dreck的建议来自libc。有许多便携式API,其中一些还针对易于包含在您的项目中进行了优化...有些像ustr有小的空间开销并支持堆栈变量。
http://stackoverflow.com/questions/195975/how-to-make-a-char-string-from-ac-macros-value – 2015-10-05 13:43:46
[C宏创建字符串](http://堆栈溢出。com/questions/798221/c-macros-to-create-strings) – rjstelling 2015-10-06 10:33:35