Search code examples
cstdiofgetc

Why does fgetc only read up to a certain byte of PNG in C?


I am trying to read the bytes of an image file in C, specifically a PNG, in the following manner:

#include <stdio.h>

int main(){
  FILE* fd = fopen("logo.png", "r");
  char c = fgetc(fd);
  while(c != EOF){
    printf("%c", c);
    c = fgetc(fd);
  }
  return 0;
}

When I run the program, I get he following:

<89>PNG^M
^Z
^@^@^@^MIHDR^@^@^@

Why does it only go to a certain byte and then completely exit reading the file?How would I fix this issue?


Solution

  • The code contains an error.

    // Wrong
    char c = fgetc(fd);
    

    The correct version is:

    // Correct
    int c = fgetc(fd);
    

    What is happening is the byte 0xff appears in your PNG file somewhere. So you get:

    char c = 0xff;
    

    But that's an overflow, and in this case it happens to result in:

    char c = -1;
    

    And EOF is also -1.

    (Note that if you read the C standard it turns out that we've actually encountered undefined behavior, but a discussion of undefined behavior can turn into a rabbit hole.)