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

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

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

如果你的MACRO_SIZE在编译时是const,你可以试试这个:

 #define MACRO_SIZE "5" snprintf(fmt_str, 100, "%" MACRO_SIZE "s", buf); 

就像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" ,这不是我们想要的。

“正确”的解决方案就是你称之为微不足道的解决方案。 所有这些聪明的宏(我自己使用m4)只会让你的代码不易管理,如果你把它留作常量。

你在这里遇到的问题是字符串不是C中的第一类数据结构。它们是一个字节数组。 因此,您必须构建您想要获得所需含义的数组,并使用sprintf构建该数组。 它不漂亮,但它是正确的。

如果您遇到性能问题并且已将其跟踪到此处,那么请删除函数调用。 但是,除非MACRO_SIZE的值重复一百次或分散在多个文件上,否则我只需更改文字。 一个宏只是假装有更多的灵活性,使用sprintf实际上给你灵活性。