阅读文本文件停止在最后一行

问题描述:

我写了一个小程序,以测试从stdin阅读文本文件:阅读文本文件停止在最后一行

int main(){ 
    char c; 

    while(!feof(stdin)){ 

     c = getchar();  //on last iteration, this returns '\n' 

     if(!isspace(c))  //so this is false 
      putchar(c); 

     //remove spaces 
     while (!feof(stdin) && isspace(c)){ //and this is true 
       c = getchar(); //  <-- stops here after last \n 
       if(!isspace(c)){ 
        ungetc(c, stdin); 
        putchar('\n'); 
       } 
     } 
    } 
    return 0; 
} 

我再传给它的小文本文件:

jimmy 8 
phil 6 
joey 7 

与最后一行(joey 7)以\n字符结尾。

我的问题是,它读取和打印最后一行后,循环回来检查更多的输入,没有更多的字符要读取,它只停在代码块中记录的行。

问题:feof()返回true的唯一方法是读取失败后,如下所示:Detecting EOF in C。为什么不是最终致电getchar触发EOF,我怎样才能更好地处理这个事件?

+4

[为什么“ while(!feof(file))“总是错?](http://*.com/q/5431941/1679849) –

+0

我不确定。它没有检测到任何失败的读取? – corporateWhore

+4

请点击链接并阅读。你应该从'getchar()'(它返回一个'int',而不是'char')的返回值,并且对EOF进行测试。作为'while()'语句的条件测试'feof()'几乎总是错误的。 –

有你的代码中的多个问题:

  • 你不包括<stdio.h>,也不<ctype.h>,或者至少你没有张贴整个源代码。使用feof()检查文件结尾。这几乎从来都不是正确的方法,如Why is “while (!feof (file))” always wrong?
  • 中强调的那样您从流中读取char变量中的字节。这可以防止EOF的正确测试,并且还会导致isspace(c)的未定义行为。将类型更改为int

这里是一个改进版本:

#include <stdio.h> 

int main(void) { 
    int c; 

    while ((c = getchar()) != EOF) { 
     if (!isspace(c)) { 
      putchar(c); 
     } else { 
      //remove spaces 
      while ((c = getchar()) != EOF && isspace(c)) { 
       continue; // just ignore extra spaces 
      } 
      putchar('\n'); 
      if (c == EOF) 
       break; 
      ungetc(c, stdin); 
     } 
    } 
    return 0; 
} 

虽然与ungetc()你的方法在功能上是正确的,这将是最好使用一个辅助变量是这样的:

#include <stdio.h> 
#include <ctype.h> 

int main(void) { 
    int c, last; 

    for (last = '\n'; ((c = getchar()) != EOF; last = c) { 
     if (!isspace(c)) { 
      putchar(c); 
     } else 
     if (!isspace(last)) 
      putchar('\n'); 
     } 
    } 
    return 0; 
} 
+0

我阅读了链接,并认为我更了解该主题。所以谢谢。但是,即使在合并你的建议更改后,仍然会在最后的'getchar()'调用中停止执行。在第11行。 – corporateWhore

+0

你的意思是*它停止*?它应该至少输出''\ n'' – chqrlie

+0

好吧,我认为这是一个eclipse调试器问题。在eclipse中,当调试行进入'while((c = getchar())!= EOF && isspace(c)'时,它会停下来并且不会继续进行下去,唯一的选择是按下停止按钮。当我编译它并在终端中运行它时,它工作得很好。对于那个很抱歉。 – corporateWhore