fscanf是否可以返回零并同时消耗输入?

fscanf是否可以消耗输入并同时返回零? 例如,如果我写

 int res; int k = fscanf(f, "%d", &res); 

并检查k == 0 ,我可以确定fscanf在同一文件f上的下一次调用是否会在调用fscanf之前的文件所在的同一位置继续?

在dasblinkenlight的回答中概述的主题的另一个变体是:

 for (int i = 0; i < 20; i++) { int rc; int number; if ((rc = scanf(" this is the time for all good men (all %d of them)", &number)) == 0) { char remnant[4096]; if (fgets(remnant, sizeof(remnant), stdin) == 0) printf("Puzzling — can't happen, but did!\n"); else { printf("The input did not match what was expected.\n"); printf("Stopped reading at: [%s]\n", remnant); } } else if (rc == 1) printf("%d: There are %d men!\n", i + 1, number); else { printf("Got EOF\n"); break; } } 

在包含以下内容的文件上尝试:

 this is the time for all good men (all 3 of them) this is the time for all good men (all 33 men) this is the time for all good men (all 333 of them) this is the time for all good men to come to the aid of the party! 

等等。

输出:

 1: There are 3 men! 2: There are 33 men! The input did not match what was expected. Stopped reading at: [men) ] 4: There are 333 men! The input did not match what was expected. Stopped reading at: [to come to the aid of the party! ] Got EOF 

请注意,转换在第二句成功,即使匹配在' men)上失败'(其中' of them) '是预期的)。 在最后一次计数(非抑制,非%n )转换之后,没有可靠的方法来获取有关匹配失败的信息。 下一次匹配尝试完全失败,但是fgets()清理了输入(读取了行的残留),然后后续尝试成功,因为格式字符串中的空格与输入中的任意空白序列匹配。 在示例数据的最后一行中,成功读取了“ this is the time for all good men ”的信息,但是“ to come to the aid of the party ”并不匹配。

这仅适用于不消耗前导空格的三个转换说明符之一 – %c%[…] (扫描集)和%n 。 所有其他转换(包括%d )将消耗空白,即使它们尝试读取的数据格式不正确也是如此。

这是一个演示此行为的示例:

 int main(void) { int ignore; char c; int a = scanf("%d", &ignore); int b = scanf("%c", &c); printf("%d %d %c\n", a, b, c); return 0; } 

如果使用前导空格将非数字输入传递给此程序,则scanf("%c", &c)将读取第一个非空白字符( 演示 )。

fscanf是否可以消耗输入并同时返回零?

考虑输入"x"

 scanf("%*d"); printf("%d\n", getchar()); 

预期的输出是'x'的ASCII代码,它被推回然后用getchar()重新读取。

现在考虑输入"-x" 。 使用我的平台,结果是45, '-'的ASCII代码。

从流中读取输入项,….输入项被定义为输入字符的最长序列….其是匹配输入序列的前缀,或者是匹配输入序列的前缀。 285)输入项目保持未读后的第一个字符(如果有)。 ( C11§7.21.6.2¶9 )

285) fscanf将最多一个输入字符推回到输入流上。 因此, strtodstrtol等可接受的一些序列对于fscanf是不可接受的。

至于我对规范的理解,这应该导致120( 'x' ),因为前缀部分"-"被读取和消耗,即使将2个字符放回更合理也是如此。 另请参阅@Jonathan Leffler的浮点情况。

因此可以消耗非空白空间输入并同时返回零。


白色空间的消耗在这里得到很好的回答, 非白色空间也是较长格式的一部分。