sscanf(input_str, "%5s", buf); //reads at max 5 characters from input_str to buf
但我需要使用%MACRO_SIZE而不是%5s
一个简单的解决方案是为同一个
创建一个格式字符串char fmt_str[100] = "";
snprintf(fmt_str, 100, "%%%ds", MACRO_SIZE);
sscanf(input_str, fmt_str, buf);
有没有更好的方法来实现同样的目标?
答案 0 :(得分:10)
就像Stefan所说的那样,但是sscanf()
能更恰当地回答这个问题,并且会有更多的宏观诡计:
#define MACRO_SIZE 5
#define FORMAT(S) "%" #S "s"
#define RESOLVE(S) FORMAT(S)
char buf[MACRO_SIZE + 1];
sscanf(input_str, RESOLVE(MACRO_SIZE), buf);
这使用C自动连接相邻的字符串文字,在编译时形成所需的格式字符串。这只适用于MACRO_SIZE
是预处理器宏的情况,而不是它是正常的运行时变量。
需要通过RESOLVE()
进行额外的宏调用,否则参数不会被解析为#define
d值,我们最终会得到格式字符串"%MACRO_SIZEs"
,这不是我们想要的。
答案 1 :(得分:8)
如果你的MACRO_SIZE在编译时是常量,你可以试试这个:
#define MACRO_SIZE "5"
snprintf(fmt_str, 100, "%" MACRO_SIZE "s", buf);
答案 2 :(得分:1)
“正确”的解决方案就是你称之为微不足道的解决方案。所有这些聪明的宏(我自己使用m4)只会让你的代码不易管理,如果你把它留作常量。
你遇到的问题是字符串不是C中的第一类数据结构。它们是一个字节数组。因此,您必须构建您想要获得所需含义的数组,并使用sprintf构建该数组。它不漂亮,但它是正确的。
如果您遇到性能问题并且已将其跟踪到此处,那么请删除函数调用。但是,除非MACRO_SIZE的值重复一百次或分散在多个文件上,否则我只需更改文字。一个宏只是假装有更多的灵活性,使用sprintf实际上给你灵活性。