如何在sscanf中传递可变长度宽度说明符?

时间:2009-02-13 07:09:02

标签: c

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

有没有更好的方法来实现同样的目标?

3 个答案:

答案 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实际上给你灵活性。