在下面的代码中,
isspace
表示空字符不是空格。稍后在代码中,fwrite
函数将包含中间和最终空字符的字符序列写入文件。
C17 标准表明
s
转换说明符“匹配一系列非空白字符”。但是,代码末尾的fscanf
只匹配但不包括第一个空字符。
标准中有什么东西可以证明这种看似矛盾的行为吗?除了
isspace
指示的字节外,是否还有被视为空白的字节?如果有,它们是什么?我在我写入文件的内容中放了一个\26
和其他一些控制字符,fscanf
读得很好。
#include <stdio.h>
#include <ctype.h>
int main(void)
{
int x = isspace('\0');
char inBuf[40];
char outBuf[] = "Hello\0world\n";
FILE *fp = fopen("MyFile.txt", "w+b");
fwrite(outBuf, 1, sizeof(outBuf), fp);
fflush(fp);
rewind(fp);
fscanf(fp, "%s", inBuf);
}
然而,代码末尾的
只匹配到但不包括第一个空字符。fscanf
这是不正确的,正如以下程序的输出是““Hello”,然后是“world”这一事实所证明的那样。
fscanf
读取整行直到换行符;它不会停在空字符处。
#include <string.h>
#include <stdio.h>
#include <ctype.h>
int main(void)
{
char inBuf[40] = {0};
char outBuf[] = "Hello\0world\n";
FILE *fp = fopen("MyFile.txt", "w+b");
fwrite(outBuf, 1, sizeof(outBuf), fp);
fflush(fp);
rewind(fp);
fscanf(fp, "%s", inBuf);
printf("\"%s\", then \"%s\".\n", inBuf, inBuf + strlen(inBuf) + 1);
}
代码末尾的 fscanf 只匹配但不包括第一个空字符。
这是不正确的。
#include <stdio.h>
int main( void ) {
char sp[] = "abc def\n";
char nul[] = "abc\0def\n";
char buf1[10];
char buf2[10];
printf( "%d\n", sscanf( sp, "%s %s", buf1, buf2 ) );
printf( "%d\n", sscanf( nul, "%s %s", buf1, buf2 ) );
}
2 // First `%s` stopped at space.
1 // First `%s` stooped at LF.
如您所见,它读取到字符串的末尾,而不是停在 NUL 处。
(您也可以在
ftell
之后使用 fscanf
来获取读取的字节数。)
你没有说明你是如何得出
fscanf
停在NUL的结论的,但我想你使用了像printf( "%s\n", inBuf );
这样的东西。 That 在第一个 NUL 处停止。不是阅读。