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

如何在sscanf中传递可变长度宽度说明符?,c,C,但我需要使用%MACRO\u大小之类的东西,而不是%5s 一个简单的解决方案是为相同的文件创建一个格式字符串 sscanf(input_str, "%5s", buf); //reads at max 5 characters from input_str to buf 有没有更好的方法来达到同样的效果?如果宏大小在编译时为常量,可以尝试以下方法: char fmt_str[100] = ""; snprintf(fmt_str, 100, "%%%ds", MACRO_SIZE);

但我需要使用%MACRO\u大小之类的东西,而不是%5s

一个简单的解决方案是为相同的文件创建一个格式字符串

sscanf(input_str, "%5s", buf); //reads at max 5 characters from input_str to buf

有没有更好的方法来达到同样的效果?

如果宏大小在编译时为常量,可以尝试以下方法:

char fmt_str[100] = "";    
snprintf(fmt_str, 100, "%%%ds", MACRO_SIZE);
sscanf(input_str, fmt_str, buf);

正如Stefan所说,但要想更准确地回答问题,并使用更大的技巧,请使用
sscanf()

#define MACRO_SIZE "5"
snprintf(fmt_str, 100, "%" MACRO_SIZE "s", buf);
这使用C将相邻字符串文本自动连接在一起,以在编译时形成所需的格式化字符串。这仅在
MACRO\u SIZE
是预处理器宏时有效,而不是在它是正常运行时变量时有效

需要通过
RESOLVE()
进行额外的宏调用,因为否则参数将无法解析为其
#define
d值,最终我们将得到一个格式字符串
%macro\u size”
,这不是我们想要的。

正确的解决方案就是您所说的微不足道的解决方案。所有这些聪明的宏(我自己会使用m4)只会让代码变得不易管理,如果你把它作为一个常量的话

这里的问题是字符串不是C中的第一类数据结构。它们是字节数组。因此,你必须构建你想要得到你想要的意义的数组,然后用sprintf构建这个数组。它不漂亮,但它是正确的


如果您遇到性能问题,并且您已经跟踪到这里,那么是的,消除函数调用。但是除非MACRO_SIZE的值被重复一百次或分布在多个文件中,否则我只需要更改文本。宏只是假装具有更大的灵活性,使用sprintf实际上给了您灵活性。

与其说宏大小是一个常量,不如说它的定义是一个简单的文本,对吗?例如,(5*25+3)(在编译时计算为常数)的定义会导致
snprintf(fmt_str,100,“%”(5*25+3)“s”,buf)
如果
宏大小
是一个表达式(例如
(4+1)
或引用另一个宏(例如
#定义宏大小(其他宏-1)
),您是否希望这样做有效?当我尝试使用
gcc-E
查看后期预处理器输出时,它没有扩展到最终值。@meowsqueak否,当然不是,因为它依赖于被视为单个字符串的相邻字符串文字。
MACRO\u SIZE
必须是一个数字。
#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);