我对下面的简单读取功能有点问题:

    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_数据数组填充.pgm中图像的8位灰度值。当w=300和h=300时,数组的大小是正确的。
在大多数情况下,它工作得很好。但有时在图像中间,getc()开始用255填充数组。
我发现当灰度值为19时会发生这种情况。这无关紧要,这个值出现在哪里。如果第三个像素是19,则第三个值和每个后续值是255。如果第127个像素是19,则第127个值和后面的每个值是255。
我真的不知道,为什么会这样。我希望有人能帮忙。
更新:好的,谢谢。二进制方式打开和使用fread代替getc的结合解决了这个问题:)
萨库

最佳答案

我不能在Unix下复制,但可以在Windows下轻松复制。问题是字符Ctrl-Z(代码0x1A)在windows下表示文本文件的文件结尾。
问题是,getc通常用于文本文件,而一些老的编辑器通常用来明确地编写Ctrl-Z来限定文本文件的结尾,getc仍然认为它是一个真正的EOF-BTW这与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);
     }

用一个简单的fread:
    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/

10-09 07:37