使用C预处理器为scanf构造字符串文字?
我正在尝试创建一个sscanf
字符串文字,以帮助在C99中防止缓冲区溢出。 目标是这样的:
#define MAX_ARG_LEN 16 char arg[MAX_ARG_LEN] = ""; if (sscanf(arg, "%"(MAX_ARG_LEN-1)"X", &input) > 0)
显而易见的“手动”解决方案如下:
#define MAX_ARG_LEN 16 #define MAX_ARG_CHARS "15" char arg[MAX_ARG_LEN] = ""; if (sscanf(arg, "%"MAX_ARG_CHARS"X", &input) > 0)
但是,在缓冲区大小为16的情况下,我更喜欢自动生成“%15X”。此链接几乎适用于我的应用程序: 将预处理程序标记转换为字符串但不处理-1。
建议?
Kernighan和Pike在他们的(优秀的)“ 编程实践 ”一书中讨论了这个问题,并得出结论,最可靠和可移植的方法是使用sprintf()
生成格式字符串。
你可以做的是将宏定义为不包括终端null的长度,然后像这样使用:
#define STR_EVALUATE(x) #x #define STRINGIFY(x) STR_EVALUATE(x) #define MAX_ARG_LEN 15 char arg[MAX_ARG_LEN+1] = ""; if (sscanf(arg, "%" STRINGIFY(MAX_ARG_LEN) "X", &input) > 0) ...
或者您可以将MAX_ARG_STRLEN定义为15,将MAX_ARG_LEN定义为MAX_ARG_STRLEN + 1并相应地工作。