feof() 和 fscanf() 在将字节 1b 扫描为 char 后停止工作。是因为它是 ascii 中的“ESC”吗?我能做些什么?

feof() and fscanf() stop working after scanning byte 1b as a char. Is it because it is 'ESC' in ascii? What can I do?

提问人:user3596853 提问时间:5/3/2014 更新时间:5/3/2014 访问量:173

问:

我目前正在编写一个处理 PPM 文件(P6 类型,而不是 P3)的程序 问题是某些图像具有字节0x1b,根据 ascii 表,该字节称为“ESC”

以下是我的代码:

所有包括那里,,,...

int main(void)
{
    FILE *finput;
    int number[7];
    char r, g, b;

    finput = fopen("my.ppm", "r");

    /*
       The code where I read the P6 numRows numColumns 255\n

       ...Lets assume that part works well 
    */


    while(!feof(finput))
    {
       num[0] = fscanf(finput, "%c", &r);    // the "num[] = " part is for debugging
       num[1] = fscanf(finput, "%c", &g);    
       num[2] = fscanf(finput, "%c", &b);


       printf("%d\n", num[0]);
       printf("%d\n", num[1]);
       printf("%d\n", num[2]);



    }
return 0; //or whatever...
}

出于某种原因,fscanf 在读取“ESC”字节后开始返回 -1(但读取它的字节不返回 -1)

因此,示例输出为:

1 -1 -1


另一方面,我读了“while(!feof()) 总是错的”和关于带有 fscanf 的大文件的文章,但我的 ppm 图像不大于 500x500 像素......

为了能够继续阅读,我可以/应该做些什么?

谢谢你的帮助!

C 循环 转义 scanf feof

评论

1赞 Barmar 5/3/2014
“while( !feof( file ) )” 的可能重复总是错误的
1赞 zneak 5/3/2014
考虑使用 instead 而不是 for(在 Windows 下处理二进制文件时会有所不同),如果您只读取一个字符,请考虑使用。"rb""r"fopenfgetc

答:

0赞 RichieHindle 5/3/2014 #1

我猜你在 Windows 上;值为 0x1b 的字节表示 Windows 上文本文件的“文件结束”。 (参见评论;这个解释是错误的,但解决方案是有效的,大概是因为数据中有0x1a)。

您应该以二进制模式打开文件:

fopen("my.ppm", "rb");

这将成功读取所有字节。(它还将读取行尾标记的 和 。\r\n

评论

2赞 ikegami 5/3/2014
0x1A (^Z) 是 Windows 上的 EOF,而不是 0x1B
0赞 RichieHindle 5/3/2014
@user3596853:你为什么接受我的回答?它对你有用吗?似乎不应该......
0赞 user3596853 5/3/2014
谢谢你,非常善良的陌生人。以二进制形式阅读它确实会有所作为。顺便问一下,二进制阅读和正常阅读之间还有其他区别吗?比如,我是否必须以不同的方式使用我的 fscanfs?还是一起使用其他东西?好吧,idk,如果是因为那个特定的字节,但使用“rb”确实解决了我的问题。这就是我接受它的原因。虽然有趣的是,认为你会发布一个解决方案,知道/期望它失败
0赞 ikegami 5/3/2014
即使解释不正确,解决方案也可能有所帮助,但我不明白如何。或者也许 OP 实际上有 1A 而不是 1B?
1赞 Michael Burr 5/3/2014
可能是 is 后面的字节(Windows 上的文本模式)。该问题指出,“读取 [0x1b 字符] 的调用不返回 -1 - 后续调用返回 -1。0x1b0x1aEOFfscanf()fscanf()