了解fgetc程序

时间:2013-07-15 08:17:52

标签: c file

我正在读一本关于c编程的书,并且不理解一个显示的例子。或者更确切地说,我不明白为什么它有效,因为我认为它不应该。

代码很简单,它读取文本文件的内容并将其输出到输出区域。据我了解,我认为

 ch = fgetc(stream);

应该在while循环中,因为它一次只读取一个int?并且需要在输出当前的int之后读取下一个int。好吧,事实证明这个代码确实工作正常,所以我希望有人可以向我解释我的谬误。谢谢!

#include <stdio.h>

int main(int argc, char *argv[]) {
    FILE *stream;
    char filename[67];
    int ch;
    printf("Please enter the filename?\n");
    gets(filename);
    if((stream = fopen(filename, "r")) == NULL) {
        printf("Error opening the file\n");
        exit(1);
    }

    ch = fgetc(stream);
    while (!feof(stream)) {
        putchar(ch);
        ch = fgetc(stream);
    }

    fclose(stream);
}

8 个答案:

答案 0 :(得分:2)

我认为你因为feof()而感到困惑:

Doc:int feof ( FILE * stream );

  

检查与流关联的文件结束指示符是否为   set,返回一个不等于零的值。

     

指标通常由流上的先前操作设置   尝试在文件结尾处读取或超过文件结尾。

   ch = fgetc(stream);      <---"Read current symbol from file"
    while (!feof(stream)) { <---"Check EOF read/returned by last fgetc() call"
        putchar(ch);        <---"Output lasts read symbol, that was not EOF"
        ch = fgetc(stream); <---"Read next symbols from file"
    }
   <-- control reach here when EOF found   

更好的方法是编写循环:

while((ch = fgetc(stream))!= EOF){ <--" Read while EOF not found"
   putchar(ch);   <-- "inside loop print a symbol that is not EOF"
}

此外,请注意:int fgetc ( FILE * stream );

  

返回内部文件位置当前指向的字符   指定流的指示符。内部文件位置   然后指示器前进到下一个字符。

     

如果在调用时流位于文件结尾,则函数返回   EOF 并设置流的文件结束指示符(feof)。

     

如果发生读取错误函数会返回EOF 并设置错误   流的指示符(ferror)。

答案 1 :(得分:1)

如你所见,它在内部和外部。外面的一个负责读取第一个字符(可能已经是文件的结尾,然后无论如何都不输入而没有打印),然后它进入循环,放置字符并读取下一个字符。只要读取的字符不是文件的结尾,循环就会继续。

答案 2 :(得分:1)

fgetc()读取char(byte)并返回该字节,字节值的读取取决于读指针的可用位置。

一旦fgetc()成功读取一个字节,读取文件指针就会移动到下一个字节。如果你读取文件,next byte将是输出,它将继续向上找到文件的末尾它返回EOF。

答案 3 :(得分:1)

如果移除fgetcwhile,请执行以下操作:

while (!feof(stream)) {
    putchar(ch);
    ch = fgetc(stream);
}
第一次调用ch时,

putchar(ch)将被取消初始化。

顺便说一句,不要使用gets,因为它可能会导致缓冲区溢出。请改用fgetsgets_s。在C11中删除了gets

答案 4 :(得分:1)

这是因为第二个fgetc正在调用while (!feof(stream))

答案 5 :(得分:1)

实际上这部分在这里:

while (!feof(stream)) {
        putchar(ch);
        ch = fgetc(stream);
    }

非常不安全,你应该避免像那样检查EOF(here为什么)。

使用fgetc阅读文件的方式如下:

int ch;
while ((ch = fgetc(stream)) != EOF) 
{
   printf("%c", ch)
}

答案 6 :(得分:1)

您提供的代码有'ch = fgetc(stream);'在While循环之前也是 'ch = fgetc(stream);'在循环体内。 顺便说一下,循环中的语句在正确表示时一次从流中检索ch。

答案 7 :(得分:1)

这是非功能性代码。永远不会输出文件的最后一个字符。 fgetc将读取最后一个字符,指针将位于文件末尾。因此,当选中while时,!feof将返回false,并且读取的字符将不会被输出。 feof在文件结束后没有阻止阅读:因为fgetc之前将调用空文件feof! 除非在控制台处理方面有一些好处,否则存在两个更好的选择: 使用feof:

while (!feof(stream)) {
    ch=fgetc(stream);
    putchar(ch);
}

不使用feof - 因为fgetc在没有其他字符时返回EOF

while ((ch=fgetc(stream))!=EOF) putchar(ch);