代码之家  ›  专栏  ›  技术社区  ›  sud03r

C文件处理中的feof()

  •  3
  • sud03r  · 技术社区  · 15 年前

    我正在逐字节读取二进制文件,我需要确定eof是否已达到。

    feof()的工作原理不是“只有在对不存在的字节发出读取请求时才设置eof”。所以,我可以有我的定制支票,比如:

    if ( fread(&byte,sizeof(byte),1,fp) != 1) {
        if(feof(fp))
        return true;
    }
    return false;
    

    但问题是,如果没有达到eof,我的文件指针会向前移动一个字节。 所以一个解决方案可能是使用 ftell() 然后 fseek() 把它放在正确的位置。

    另一种解决方案可能是在某个临时存储器中预先缓冲字节。

    5 回复  |  直到 15 年前
        1
  •  6
  •   jamesdlin    15 年前

    如果一次读取一个字节,通常的方法是使用 fgetc :

    int c;
    while ((c = fgetc(fp)) != EOF) {
       // Do something.
    }
    

    然后你就不需要处理 feof

        2
  •  3
  •   Kristopher Johnson    15 年前

    我通常会这样做:

    int get_next_char(FILE* fp, char *ch)
    {
        return fread(ch, sizeof(char),1, fp) == 1;
    }
    
    // main loop
    char ch;
    while (get_next_char(fp, &ch))
        process_char(ch);
    
    if (!feof(fp))
        handle_unexpected_input_error(fp);
    
        3
  •  2
  •   Community CDub    7 年前

    最好的方法是构造代码,以便尝试读取一些数据,如果由于到达文件末尾而导致读取失败,则可以在那里处理它(例如,请参阅 Kristopher Johnson's answer ).

    如果你非常讨厌这个,你可以用 ungetc

    int c = fgetc(fp);
    if (c == EOF)
    {
        // handle eof / error
    }
    else
    {
        ungetc(c, fp);
    
        // the next read call is guaranteed to return at least one byte
    
    }
    
        4
  •  0
  •   KevinDTimm    15 年前

    我不清楚,但是如果您有兴趣在读取字节之前知道EOF是否已达到,请将feof()测试放在fread()之前,而不是之后。
    实际上,如果我没看错的话,你甚至不想做fread,所以:

    return feof(fp) ? true : false;
    
        5
  •  0
  •   abelenky    15 年前

    我建议使用:

    fseek(myFile, 0, SEEK_END);
    fileLen = ftell(myFile);
    fseek(myfile, 0, SEEK_SET);
    

    当您第一次打开文件以确定长度时。然后设置你的读循环,使其永远不会读到末尾。你可以用 ftell 找出你现在的位置,并与fileLen进行比较,找出你还需要走多远。