繁体   English   中英

EOF-scanf和printf

[英]EOF - scanf and printf

我想在这里做一个简单的练习,但是我需要先了解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("%s\n", s1[j]);

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

您所拥有的是一个循环,该循环将单词读入缓冲区,直到到达EOF(对这些单词不执行任何操作),然后执行printf打印缓冲区的内容。 printf 循环之后(不在循环中),因此在循环完成执行一次。 那时,缓冲区将包含读取的最后一个字,因此将被打印出来。

EOF返回测试的意思是“没什么要读取的”,它不一定是文件的结尾(可能是某种错误情况),但是实际上区别可以忽略。 循环直到您的读取函数返回EOFNULL (取决于函数)是一种好习惯。

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

如果要存储单词以供以后处理,则需要将它们存储在某个位置。 这意味着声明一些存储空间,或在堆上分配空间,并进行一些簿记以跟踪已使用/分配的空间。

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

因为它仅打印从文件读取的最后一个内容(“ stackoverflow”)。 这是由while(...);结束后的分号引起的while(...); -这意味着您正在执行while(...) { /* do nothing */} -这可能不是您想要的

另外, printf("%s",s1)!='\\0'; 毫无意义。 一方面, printf返回打印的字符数- '\\0'是作为字符常量写入的零值。 当然,不使用某种比较就对结果进行!= 0也是毫无意义的。

如果您想一次读取一行,请使用fgets而不是scanf 当找到空白时, scanf将停止读取。 fgets会读取到该行的末尾。

使用fgets() 简单而甜美

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

这是文件尾在C中的工作方式。输入通道称为输入流 磁盘文件和stdin都是输入流。 “文件结束”状态是流具有的标志,当您尝试从流中读取该标志时将触发该标志,但是事实证明流中不再有字符,并且永远不会有任何字符更多。 (例如,如果流仍处于活动状态,但仅在等待用户输入,则不将其视为文件结束;读取操作将被阻止)。

流可以具有其他错误状态,因此循环进行直到设置“文件结束”通常是错误的。 如果流确实进入错误状态,则您的循环将永远不会退出(也称为“无限循环”)。

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

例如,如果getchar()scanf是文件末尾,而且流处于错误状态,则它将返回EOF

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM