38

我有一个文本文件,每行都有字符串。我想为文本文件中的每一行增加一个数字,但是当它到达文件末尾时,它显然需要停止。我曾尝试对 EOF 进行一些研究,但无法真正理解如何正确使用它。

我假设我需要一个while循环,但我不知道该怎么做。

4

4 回答 4

101

如何检测 EOF 取决于您用于读取流的内容:

function                  result on EOF or error                    
--------                  ----------------------
fgets()                   NULL
fscanf()                  number of succesful conversions
                            less than expected
fgetc()                   EOF
fread()                   number of elements read
                            less than expected

检查输入调用的结果是否符合上述条件,然后调用feof()以确定结果是否是由于遇到 EOF 或其他错误。

使用fgets()

 char buffer[BUFFER_SIZE];
 while (fgets(buffer, sizeof buffer, stream) != NULL)
 {
   // process buffer
 }
 if (feof(stream))
 {
   // hit end of file
 }
 else
 {
   // some other error interrupted the read
 }

使用fscanf()

char buffer[BUFFER_SIZE];
while (fscanf(stream, "%s", buffer) == 1) // expect 1 successful conversion
{
  // process buffer
}
if (feof(stream)) 
{
  // hit end of file
}
else
{
  // some other error interrupted the read
}

使用fgetc()

int c;
while ((c = fgetc(stream)) != EOF)
{
  // process c
}
if (feof(stream))
{
  // hit end of file
}
else
{
  // some other error interrupted the read
}

使用fread()

char buffer[BUFFER_SIZE];
while (fread(buffer, sizeof buffer, 1, stream) == 1) // expecting 1 
                                                     // element of size
                                                     // BUFFER_SIZE
{
   // process buffer
}
if (feof(stream))
{
  // hit end of file
}
else
{
  // some other error interrupted read
}

注意形式都是一样的:检查读操作的结果;如果失败,检查 EOF。你会看到很多例子,比如:

while(!feof(stream))
{
  fscanf(stream, "%s", buffer);
  ...
}

这种形式并不像人们想象的那样工作,因为在您尝试读取文件末尾之后feof()才会返回 true 。结果,循环执行了太多次,这可能会也可能不会让您感到悲伤。

于 2009-12-02T22:55:01.907 回答
13

一种可能的 C 循环是:

#include <stdio.h>
int main()
{
    int c;
    while ((c = getchar()) != EOF)
    {
        /*
        ** Do something with c, such as check against '\n'
        ** and increment a line counter.
        */
    }
}

现在,我会忽略feof和类似的功能。经验表明,在错误的时间调用它并在认为尚未达到 eof 的情况下处理两次太容易了。

要避免的陷阱:char用于 c 的类型。getchar返回下一个转换为 an 的字符unsigned char,然后再转换为 an int。这意味着在大多数 [sane] 平台上, 的值EOF和有效的 " char" 值c不会重叠,因此您永远不会意外检测到EOF'normal' char

于 2009-12-02T21:51:57.310 回答
0

从文件读取后,您应该检查 EOF。

fscanf_s                   // read from file
while(condition)           // check EOF
{
   fscanf_s               // read from file
}
于 2014-06-05T12:15:13.533 回答
0

我建议你使用 fseek-ftell 函数。

FILE *stream = fopen("example.txt", "r");

if(!stream) {
    puts("I/O error.\n");
    return;
}

fseek(stream, 0, SEEK_END);
long size = ftell(stream);
fseek(stream, 0, SEEK_SET);

while(1) {

    if(ftell(stream) == size) {
        break;
    }

    /* INSERT ROUTINE */

}

fclose(stream);
于 2020-01-19T21:52:43.967 回答