我的代码有点问题。目前我只有一行(char* string
,最后有\0
),我希望在特殊字符上检查该行。因此我使用了以下代码:
char lineJunk;
if(sscanf(lineContent, "%*[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+=\0/{}:]%c", &lineJunk)){
return 0;
}
现在我的编译器会吐出以下警告:
Multiple markers at this line
- no closing ‘]’ for ‘%[’ format [-Wformat=]
- embedded ‘\0’ in format [-Wformat-contains-nul]
- too many arguments for format [-Wformat-extra-args]
这些警告仅在我的sscanf中有\0
时出现。然而,否则代码将无效,因为我正在检查的行在其末尾有\0
。当我使用\\0
代替\0
时,警告会消失,但代码不再有效。仅\
也不起作用。
有人知道解决方案吗?
答案 0 :(得分:3)
您没有正确使用sscanf()
来解释警告
没有结束]
表示您的格式字符串没有结束]
这是必需的,因为您传递的格式为[
。
格式字符串中的关闭]
确实是“ not ”,因为格式字符串中嵌入了'\0'
,因此实际格式字符串为< / p>
"%*[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+="
这是因为格式字符串中有明确的'\0'
,这也导致了之前的警告。
格式字符串中有一个由编译器在其末尾添加,以标记结尾,因此它成为合法的c字符串,在某种意义上,您可以将其传递给strlen()
并且期望nul
终结符存在的其他函数。
通过将其嵌入格式字符串中,您将在插入的位置标记字符串的结尾,这就是格式字符串是我在第1点中所说的字符串的原因。
您正在使用*
修饰符丢弃匹配的值,您需要将其删除以使传递的参数有用,因为您正在丢弃匹配的值,因此不需要参数。
如果您希望一次一个字节地遍历字符串,直到找到'\0'
,那么sscanf()
与'\0'
无法匹配,在这种情况下,长度应事先知道。
答案 1 :(得分:1)
'\0'
的{{1}}格式为<{1}} 。 sscanf(char *src, char *format, ...)
会在到达sscanf()
中的'\0'
时停止扫描。因此src
永远不会提供sscanf()
进行扫描。
正如@iharob所述,格式中的'\0'
有问题,因为'\0'
将其视为格式的结尾。这就是编译器警告的内容。
sscanf()
// Eliminate `\0` from the format.
#define SKIP "%*[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+=/{}:]"
if(sscanf(lineContent, SKIP "%c" , &lineJunk) == 1) {
return 0;
}
与典型的ASCII编码一样,应该是连续的,快捷方式是:A-Z
-
请注意,更好地检查#define SKIP "%*[A-Za-z0-9+=/{}:]"
结果以及代码需要的内容:sscanf()
而不是非零。在特定情况下,1
将返回sscanf()