2013-08-30 185 views
2

我正在阅读一个文本文件,使用while(!feof)循环迭代, 迭代,但是每当我使用这个条件时循环会迭代一个额外的时间。优雅的方式来确定EOF?

我解决了这个问题,这个“修修补补”代码

while (stop == FALSE) 
{ 
... 

     terminator = fgetc(input); 
     if (terminator == EOF) 
      stop = TRUE; 
     else 
      fseek(input, -1, SEEK_CUR); 
} 

但它看起来和感觉非常糟糕。

+2

可能的重复[为什么iostream :: eof里面的循环条件被认为是错误的?](http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-错误) – 2013-08-30 14:15:13

+2

可能是第20个关于CIO在过去几天中的问题,可能我们需要一个关于该社区维基页面的文章 – jev

+0

@ H2CO3:从技术上讲,这不是iostream问题的重复,因为这是特别的C,另一个是C++。 –

回答

7

你可以采取的事实,为分配的值被读分配得到评估,在这种情况下性格优势:

while((terminator = fgetc(input))!= EOF) { 
    // ... 
} 
+0

如果'!= EOF'不会让光标保持前面的字符? – Quaker

+0

@奎克不,为什么呢? – 2013-08-30 14:11:42

+0

由于fgetc每次提前指示一个字符,如果终止符!= EOF,那么终止符将保存相关的字符,并且指示符将在其之前。 – Quaker

6

下面是一个地道的例子(source):

fp = fopen("datafile.txt", "r"); // error check this! 

// this while-statement assigns into c, and then checks against EOF: 

while((c = fgetc(fp)) != EOF) { 
    /* ... */ 
} 

fclose(fp); 
+0

感谢您发布此信息。在这里,“feof()”这个问题的热情非常令人厌倦。 – unwind

+0

@unwind顺便说一句,其他答案也不正确吗? – 2013-08-30 14:12:59

+0

Brian,我正在逐行读取文本文件,该函数将整行读入一个字符串。您的解决方案是否会导致修剪后的字符串(缺少该行的第一个字符)? – Quaker

0

同样你CA读取行由行:

char buf[MAXLINE]; 
// ... 
while((fgets(buf,MAXLINE,stdin)) != NULL) { 
     do_something(buf); 
} 

由于fgets复制检测到的换行符,因此可以通过检查倒数第二个缓冲区元素来检测 行结束。您可以使用 realloc来调整缓冲区大小(请确保您保留指向缓冲区开始的指针,但将buf+n传递到下一个fgets,其中n是读取字符数)。从关于fgets标准:

从流中读取字符和将它们存储为C字符串到STR直到(NUM-1)的字符已被读出或达到任一换行或档案结尾,取其首先发生。换行符使fgets停止读取,但它被函数视为有效字符,并且包含在复制到str的字符串中。

或者,您可以使用fread()一次性阅读整个文件(请参阅链接后的示例)。

+0

这不是一个选项,因为最大线长度是未知的...... – Quaker