EOF-扫描和打印

EOF - scanf and printf

本文关键字:打印 扫描 EOF-      更新时间:2023-10-16

我想在这里做一个简单的练习,但我首先需要了解EOF是如何工作的。

void main()
{
    char s1[1000];
    while (scanf("%s", s1)!=EOF)
        ;
    printf("%s",s1);
}

这个想法是在输入中有多行,并显示它们。

我的问题是,如果我把

Hello World
This is stackoverflow

当调用printf时,它只打印

stackoverflow

为什么它不打印所有内容?我该如何打印?

关注

删除分号;:

    while (scanf("%s", s1)!=EOF)
        printf("%s",s1);

请注意,这仍然会在文件末尾显示出奇怪的行为,具体取决于它的结束方式。此外,它将输入拆分为单词,这些单词由空格或新行分隔。您可能想要简单地拆分成行。

因此,你可能会得到更好的服务,例如:

    while (gets(s1)!=NULL)
        puts(s1);

此代码片段逐行读取您的输入,直到文件结束。

要读取所有内容(或尽可能多的缓冲区(,您可以使用:

    char s1[1000] = "";
    fread(s1, sizeof(s1) - 1, 1, stdin);
    puts(s1);

然而,我喜欢的读取文本文件的方法是:

    using namespace std;
    string line;
    while (getline(cin, line))
    {
        cout << line << endl;
    }

这是因为通常我想逐行处理一个文件,而getlinestring确保了行缓冲区总是足够大。

您可能想要这个:

  char s1[1000][20];
  int i = 0 ;
  while (!feof(stdin))
     fgets(s1[i++], 20, stdin) ;
  int j ;
  for (j = 0; j < i; j++)
    printf("%sn", s1[j]);

在这里,您最多可以输入1000行,最长19个字符。

您所拥有的是一个循环,它将字读取到缓冲区中,直到它达到EOF(对这些字不做任何处理(,然后是一个printf来打印缓冲区的内容。printf在循环之后(不在其中(,因此在>循环完成之后执行一次。到那时,缓冲区将包含读取的最后一个单词,所以这就是打印的内容。

EOF返回测试意味着"不再需要读取任何内容",这不一定是文件的末尾(可能是某种错误条件(,但在实践中可以忽略这种区别。循环直到您的读取函数返回EOFNULL(取决于函数(是一种很好的做法。

如果你想在阅读每个单词时打印它,你需要在循环中放入一个printf

如果你想把这些单词存储起来以便以后处理,你需要把它们存储在某个地方。这意味着声明一些存储空间,或者在堆上分配空间,并进行一些记账来跟踪您使用/分配了多少空间。

如果想要而不是单词,则应使用fgets而不是scanf("%s"。请注意,当没有其他内容要读取时,fgets返回NULL而不是EOF

因为它只打印从文件中读取的最后一个东西("stackoverflow"(。这是由while(...);末尾的分号引起的——这意味着你正在执行while(...) { /* do nothing */}——这可能不是你想要的

此外,printf("%s",s1)!='';完全没有意义。首先,printf返回打印的字符数——''是作为字符常量写入的值零。当然,在不使用某种比较的情况下对结果进行!= 0也是毫无意义的。

如果您想一次读取一行,请使用fgets而不是scanfscanf在发现空白时将停止读取。fgets将一直读取到该行的末尾。

使用fgets()。简单甜美的

char buf[1000];
while (fgets(buf, sizeof buf, stdin) != NULL) {
  fputs(buf, stdout);
}

以下是文件结尾在C中的工作方式。输入通道被称为输入流;磁盘文件和CCD_ 26都是输入流。"文件结尾"状态是流具有的一个标志,当您尝试从流中读取时,该标志会被触发,但事实证明,流中没有更多的字符,而且永远不会有更多的字符。(例如,如果流仍然处于活动状态,但只是在等待用户输入,则不认为它是文件结尾;读取操作将被阻止(。

流可能有其他错误状态,所以循环直到设置"文件结尾"通常是错误的。如果流确实进入错误状态,那么循环将永远不会退出(也就是"无限循环"(。

文件结束状态可以通过feof进行检查。然而,一些输入操作也可能会发出错误信号,或者返回它们想要读取的实际数据。这些函数可以返回值EOF。通常,这些函数在两种情况下都返回EOF:文件结束和流错误。这与feof不同,后者仅在文件结束时返回true

例如,如果是文件结尾,getchar()scanf将返回EOF,但如果流处于错误状态。

因此,可以使用getchar()的结果作为循环条件,但不能单独使用feof

此外,有时使用scanf() != EOF作为循环条件是不可行的。可能没有流错误,只是您请求的数据不在那里。例如,如果您扫描"%d",但流中有字母。相反,最好检查转换是否成功(scanf返回它执行的成功转换次数(。然后,当您退出循环时,您可以继续调用feofferror,看看这是由于文件结尾、错误还是意外输入。