我有一个代码,使用构建工具v110编译时工作得很好。最近我将工具链升级到v141(vs 2k17),并且使用sscanf的一些功能不再起作用了。
停止工作的sscanf调用使用这个特定的格式字符串:"%s %[^\0]"
。它期望一个包含1个字符串的流字符串,后跟一个空格和另一个字符串,这些字符串必须放在一个缓冲区中供以后处理。第一个字符串被正确复制到第一个缓冲区但第二个字符串不是(sscanf返回1而不是2)。
有人遇到这个问题或者想知道为什么会这样?
用于测试问题的代码示例:
#include <stdio.h>
#include <tchar.h>
int main()
{
char str1[100], str2[100];
memset(str1, 0, sizeof(str1)); memset(str2, 0, sizeof(str2));
int i = sscanf("+nf foo", "%s %[^\0]", str1, str2);
return 0;
}
序列\0
编码一个零字节(ASCII字符NUL),它在C / C ++中是一个字符串终止符。
所以你的格式化字符串实际上是"%s %[^"
与另一个字符长字符串"]"
可能跟随它(可能,因为编译器可能会注意到字符串终止并丢弃未使用的尾部)。
编辑
作为字符串终止符,NUL字符实际上不能出现在输入字符串中(尽管它可能出现在文件流中!但是我不确定fscanf()
将如何处理),所以你不需要看对于它与格式说明符。如果您只需要将输入字符串的两个部分读入两个char
数组,只需使用"%s%s"
:
sscanf("+nf foo", "%s%s", str1, str2);
如用户n.m所述。在主题注释中我使用的字符串(“%[^\0]
”)不起作用,因为char“\0
”将被转换为ASCII NUL,在指定符%[]
的正确结束之前结束格式字符串。在这种情况下使用的正确字符串(当您需要使用说明符%[]
来读取所有字节而不是ASCII NUL时)是“%[\1-\377]
”