在读取图像时使用getc?

在读取图像时使用getc?,c,image,C,Image,我对以下简单的读取函数有点问题: 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("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);
         }
    }
printf(“要打开的文件:”);
扫描频率(“%s”,输入);
如果((fp=fopen(输入,“r”))==NULL){
printf(“错误:无法打开%s!”,输入);
} 
否则{
如果(读取pgm hdr(fp、w和h)!=-1){
printf(“***成功--%s--打开***\n”,输入);
printf(“***已识别PGM文件,正在将数据读入图像结构***\n”);
对于(i=0;i
在循环中,img_数据数组由.pgm中图像的8位灰度值填充。当w=300和h=300时,数组的大小正确。 在大多数情况下,它工作得很好,但是有时在图像中间,GETC()开始用255。 我发现当灰度值为19时会发生这种情况。不管这个值发生在哪里。如果第三个像素为19,则第三个值和每个后续值都是255。如果第127个像素为19,则第127个值和每个后续值都是255

我真的不知道,为什么会这样。我希望任何人都能帮助我

更新:好的,谢谢。以二进制模式打开和使用fread代替getc的组合解决了问题:)


Saku

255将是
getc
返回
EOF
的结果

要测试
EOF
,需要将值存储在
int
中:

     for (i = 0; i < w * h; i++) {
          int tmp = getc(fp);
          if (tmp == EOF) {
              /* Handle EOF */
              printf("EOF after readin %d bytes out of %d!!!\n", i, w*h); 
              break;
          }
          img_data[i] = tmp;
     }
(i=0;i{ int tmp=getc(fp); 如果(tmp==EOF){ /*处理EOF*/ printf(“读取%d字节中的%d字节后的EOF!!!\n”,i,w*h); 打破 } img_data[i]=tmp; }
我无法在Unix下复制,但可以在Windows下轻松复制。问题在于Windows下的字符Ctrl-Z(代码0x1A)表示文本文件的文件结尾

问题是,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在第一种方式中为h或在第二种方式中为n*h。

img_数据的类型是什么[i]
?AFAIR,
getc()
/
fgetc()
返回
int
unsigned char
转换为
int
)img_数据是一个无符号的字符数组。您应该以二进制模式打开文件。使用
fopen>(输入,“rb”)
@unwindOk,这就是我的想法。但我想读取每个像素,而不仅仅是19之前的像素。为什么读取19时getc()会返回EOF?@Saku我不知道。你确定文件包含所有字节并且不会在前19之后结束吗?另外,尝试unwind的建议,在文本模式下读取二进制文件不是一个好主意。
    n = fread(img_data, w, h, fp); // or fread(img_data, 1, w * h, fp);