C 语言中的 feof 错误循环

feof wrong loop in c

提问人: 提问时间:7/9/2011 更新时间:7/9/2011 访问量:972

问:

我使用下面的代码从文件中读取一个字符并将其替换为另一个字符, 但是我在进入文件末尾时有一个error.loop。

怎么了?

我在 linux (netbeans IDE) 上测试了这段代码,它是正确的并且运行良好,但是当我尝试在 Windows 中使用 VS 2008 时,我发现了一个非结束循环。

//address = test.txt

FILE *fp;
fp=fopen(address,"r+");
if(fp == 0)
{
    printf("can not find!!");
}
else
{
    char w = '0';  /// EDIT : int w;
    while(1)
    {
        if((w = fgetc(fp)) != EOF)
        {
            if((w = fgetc(fp)) != EOF)
            {
                fseek(fp,-2,SEEK_CUR);
                fprintf(fp,"0");
            }
        }
        else
        {
            break;
        }
    }
} 
fclose(fp);
C feof

评论

0赞 littleadv 7/9/2011
为什么不使用 feof() 函数而不是 while(1) 循环>
0赞 David Grayson 7/9/2011
有趣的是,这在 Linux 中对你有用。当 w 是 char 时,也许 (w = fgetc(f)) 的类型定义不明确?好好调查一下......
0赞 7/9/2011
我测试了它,但它也不起作用
0赞 7/9/2011
如果我在 while 中使用 feof(),那么如果我有 7 个字符,我最后将有 8 个字符;如果它是“123456”,那么输出是“0000000”,这意味着一个字符添加到输入中。
2赞 David Grayson 7/9/2011
你实际上想通过这个循环完成什么?

答:

6赞 cnicutar 7/9/2011 #1

您将 fgetc 的结果存储在 char 中,而不是 int 中。

char w = '0'; /* Wrong, should be int. */

顺便说一句,这个问题在 C FAQ 中提到过。

如果 type 是 ,则实际 EOF 值将被截断(通过具有 它的高阶位被丢弃, 可能导致 255 或 0xff) 和 不会被识别为 EOF,导致实际上无限 输入charunsigned

编辑

再读一遍你的问题,你找回两个字符并写一个字符的方式非常可疑。这很可能导致无限循环。

编辑2

你(可能)想要这样的东西(未经测试):

while ((w = getc(fp)) != EOF) {
    fseek(fp, -1, SEEK_CUR);
    fprintf(fp, "0");
    fflush(fp); /* Apparently necessary, see the answer of David Grayson. */
}

评论

0赞 7/9/2011
是的,你是对的......这是问题所在,但解决方案是什么?
1赞 7/9/2011
我测试了您的 edit2,其中我有一个非结束循环,当我使用 Ctrl+C 中断然后用记事本打开文件时,我看到零的数以百万计
0赞 cnicutar 7/9/2011
@mimad 你必须用我发布的那个替换你的整个时间
1赞 Bo Persson 7/9/2011
在写入和读取之间切换时,您可能需要另一个 fseek。
1赞 cnicutar 7/9/2011
@David 格雷森很好 :-)我自己不太喜欢假设。
3赞 David Grayson 7/9/2011 #2

cplusplus.com 上的 fopen 文档说:

对于读取和 允许书写(或附加) (包含“+”号的那些),, 流应刷新 (fflush) 或 重新定位(fseek、fsetpos、rewind) 在读取操作之间 后跟写入操作或 写入操作后跟 读取操作。

我们可以在 之后添加一个调用来满足该要求。fflushfprintf

这是我的工作代码。它创建一个名为的文件,在程序退出后,该文件的内容将是 .example.txt000000000000n

#include <stdio.h>

int main(int argc, char **argv)
{
    FILE * fp;
    int w;

    fp = fopen("example.txt","w");
    fprintf(fp, "David Grayson");
    fclose(fp);

    fp = fopen("example.txt","r+");
    while(1)
    {
        if((w = fgetc(fp)) != EOF)
        {
            if((w = fgetc(fp)) != EOF)
            {
                fseek(fp,-2,SEEK_CUR);
                fprintf(fp,"0");
                fflush(fp);  // Necessary!
            }
        }
        else
        {
            break;
        }
    }
    fclose(fp);
}

这是在 Windows 中使用 MinGW 进行测试的。