我对以下简单的读取功能有一个小问题:
printf("File to be opened: ");
scanf("%s", input);
if ((fp = fopen(input, "r")) == NULL) {
printf("ERROR: can't open %s!", input);
}
else {
if (read_pgm_hdr(fp, &w, &h) != -1) {
printf("*** SUCCESS --%s-- opened ***\n", input);
printf("*** PGM file recognized, reading data into image struct ***\n");
for (i = 0; i < w * h; i++) {
img_data[i] = getc(fp);
}
}
在循环中,img_data 数组填充了 .pgm 格式图像的 8 位灰度值。当 w = 300 和 h = 300 时,数组具有正确的大小。 在大多数情况下,它工作正常。但有时在图像中间,getc() 开始用 255 填充我的数组。
我发现当灰度值为 19 时会发生这种情况。这个值出现在哪里并不重要。如果第3个像素是19,那么第3个和后面的值都是255。如果第127个像素是19,那么第127个和后面的值都是255。
我真的不知道为什么会这样。我希望任何人都可以提供帮助。
更新:好的,谢谢。以二进制模式打开并使用 fread 而不是 getc 的组合解决了问题:)
佐久
最佳答案
我无法在 Unix 下重现,但在 Windows 下可以轻松重现。问题是字符 Ctrl-Z(代码 0x1A)在 Windows 下代表文本文件的文件结束。
问题是 getc 通常用于文本文件,因为一些旧的编辑器习惯于明确编写 Ctrl-Z 来分隔文本文件的末尾,getc 仍然认为它是一个真正的 EOF - 顺便说一句,这与Klas Lindbäck 的回答。当您以 "r"
模式打开文件时,它会隐含地作为文本文件打开。
修复很简单:将文件作为二进制文件打开。
if ((fp = fopen(input, "rb")) == NULL) ...
(注意 b)应该足够了。
对于问题中引用的字符 19,我用 ASCII 字符表进行了测试,最后正确的是... Ctrl-Y = 0x19 ... 但罪魁祸首确实是 Ctrl-Z = 0x1A。
无论如何,您应该替换一次读取一个字符的循环:
for (i = 0; i < w * h; i++) {
img_data[i] = getc(fp);
}
有一个简单的恐惧:
n = fread(img_data, w, h, fp); // or fread(img_data, 1, w * h, fp);
并控制n在第一种方式中是h或者在第二种方式中是n * h。
关于c - 读取图像时使用getc?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30782214/