1
    int i, j;
    for (i = (*pgm).height - 1; i >= 0; i--)
        for (j = 0; j < (*pgm).width; j++)
        { 
            fscanf(file, "%c", &(*pgm).data[i][j]);
        }
}

This is a part of my function for reading a PGM file byte by byte. In this for, after something like 2000 bytes, every byte that it reads is 0.

Instead of reading the image like this enter image description here

I get it like this

enter image description here

How can i solve this?

Edit: this is the definition of the pgm:

typedef struct PGM
{
    int width;
    int height;
    int maxValue;
    unsigned char data[500][500];
} PGM;
  • 1
    Why do you write `(*pgm).foo` instead of `pgm->foo`? How is `pgm->data` defined and initialized? – rici Aug 03 '15 at 22:23
  • this is how my teacher made his notes. I've put the definition of pgm in the post. It is initialized as PGM pgm; – Gabriel Ioniță Aug 03 '15 at 22:28
  • 2
    your teacher must have pretty good reasons for reading an image file in such an awful way (one byte at a time and using fscanf!). Tell him/her to read at least one image line at a time (e.g. using `fread`) and avoid parsing the input.. it's a binary file after all – Pynchia Aug 03 '15 at 22:31
  • PGM is half text/ half binary. The header with the height, width, and max are in ASCII with whitespace. The maxvalue must be followed by exactly one whitespace character (usually a newline), after which the rest of the file is binary. – Lee Daniel Crocker Aug 03 '15 at 22:37
  • ...I'm assuming that's the usual "P5" format. There's also a pure-text "P2" format. – Lee Daniel Crocker Aug 03 '15 at 22:42
  • I understand that, but i can't read all the binary part of the file. Yes, I'm using the "P5" format. – Gabriel Ioniță Aug 03 '15 at 22:42
  • I have no idea whether `fscanf()` is capable of that. `fread()` or `read()` are the way to go. – Lee Daniel Crocker Aug 03 '15 at 22:48
  • the data area of the image is pixels (depending on another field, 24 bit or 32 bit pixels. The height and width values in the ;pgm header are pixel counts, not byte counts. (and the actual lines of pixels are rounded up (in the image) to be a multiple of 4. Therefore, the header values for width need to be multiplied by 3 or 4 and then rounded up to a multiple of 4 – user3629249 Aug 03 '15 at 22:48
  • That depends on the maxvalue. If maxvalue is 255, for example, then pixels are 1 byte. – Lee Daniel Crocker Aug 03 '15 at 22:49
  • when using fscanf(), the read will not continue beyond any white space ('\0', tab, '\n') if any byte happens to be the same as a white space character, then the fscanf() will fail (and continue to fail). To check this out, always check (!=1) the returned value (not the parameter value) from fscanf(). For more info, please read the man page for fscanf(). strongly suggest: use readline() or fgets() or fgetc() or similar – user3629249 Aug 03 '15 at 22:55
  • 1
    @user3629249 I don't think any of that is true. – melpomene Aug 03 '15 at 22:59

1 Answers1

1

If you are using Windows, you need to make sure that you open the file in binary mode. Otherwise, a byte which happens to have the value 26 (0x1A) will be interpreted as an end of file, after which no further bytes will be read. (Other modifications will also be made, which will produce other problems.)

On any OS, it is best to open binary files in binary mode, but on Windows it is hugely important.

It is also important to check the return value of fscanf.

Fscanf is an awful way of reading a binary file, for what its worth. If your teacher told you to do that, you might want to have a discussion with him about good programming practice.

rici
  • 234,347
  • 28
  • 237
  • 341