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

时间:2017-12-15 20:00:18

标签: c scanf

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

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

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

3 个答案:

答案 0 :(得分:3)

仅适用于不使用前导空格的三个转换说明符之一 - %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)将读取第一个非空白字符(demo)。

答案 1 :(得分:3)

dasblinkenlight' answer中概述的主题的另一个变体是:

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

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

答案 2 :(得分:2)

  

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

因此可能使用非空格输入并同时返回零。

空格的消费得到了很好的回答here以及non white space作为较长格式的一部分。

相关问题