-1

I am working on inputting a 2d pixel array from a PPM file with the one I am testing being of width and length 5. Also I am aware that in a ppm file that is rgb it has 3 color values not just one. I had forgotten that before I wrote this code, but the problem still persists even with the update to it and the problem still exists in the same way. I have simplified the problem to just the array as to isolate the problem. From what I can tell this seems to be both dropping characters and replacing some with new line characters as well. Any insight into why this is happening would be greatly appreciated and if I forgot to add something I will update this as soon as I am aware.

#include <stdio.h>

int main(int args, char *argv[]) {
    int w = 5, h = 5;

    FILE *f = fopen(argv[1], "rb");
    int c = 'a';//I am setting this so as to avoid the off chance of c being defined as EOF
    for(int i = 0; i < h && c != EOF; i++) {
        for(int j = 0; j < w && (c = fgetc(f)) != EOF; j++) printf("%c", c);
        fgetc(f);//To remove the '\n' character I am not using fgets because it stops at '\n' character and it is possible for a rgb value to be == to '\n'
        printf("\n");
    }
    fclose(f);
    return 0;
}

Test File I am using:

12345
abcde
12345
abcde
12345

Output I am getting:

12345

abcd

123
5
ab
de
1

Thanks in advance!

Edit: This is running on the windows 10 command prompt

  • 1
    I bet this is on a Windows machine, right? Or at least your input file has crlf line endings. – Fred Larson Aug 10 '16 at 19:40
  • Yep, cause the 'missing' character is moving backwards one position in each line - which means the extra `fgetc` is discarding it. – kdopen Aug 10 '16 at 19:41
  • Indeed, looks like your file is in fact a text file with Windows line endings, even though you open it in binary mode. Hints, use debugger, print read characters' ASCII values instead of characters themselves, and don't cram so many things in one line, so things are easier to debug. – hyde Aug 10 '16 at 19:43
  • There is no 2D array in your code and nothing which can represent one or point to one. – too honest for this site Aug 10 '16 at 20:01
  • 1
    [ppm](https://en.wikipedia.org/wiki/Netpbm_format) appears to be a text file. Perhaps open file in text mode? – chux - Reinstate Monica Aug 10 '16 at 20:13
  • 1
    @chux It depends on the "magic number", P4 P5 and P6 (ppm RGB) are actually binary. – Bob__ Aug 10 '16 at 20:16
  • @Bob__ Good to know. LSNED. – chux - Reinstate Monica Aug 10 '16 at 20:20
  • @Olaf does the array have to be stored for it to count as a 2D array? the problem was inputting a binary 2d array of bytes. "2D Array" is the format of the data within the file I was reading, if this is indeed not what a 2d array is, then I will remove the tag, but this does still fit the definition of what a multidimensional array is, so as I see it your comment is unjustified. If you can convince me otherwise I will remove the tag immediately. (took me a while to respond because I was considering if it was worth it or not) – Egon Gilstrom Aug 16 '16 at 06:37
  • @EgonGilstrom: I commented more on your text "I am working on inputting a 2d pixel array ..." and suspected a very common missconception- But yes, if you don't mean a C array, nor want one, you of course can process the file on-the-fly (hi, Marty Mc!). – too honest for this site Aug 16 '16 at 11:43

1 Answers1

0

The problem is that '\n' on a Windows machine actually ends up producing two characters, a carriage return (ASCII code 13) and a line feed (ASCII code 10). When you open a file in binary mode, those line endings are not translated back to a single character. You're only accounting for one of these characters, so you're getting off by a character on each line you read.

To illustrate this, replace your printf("%c", c);" with printf("%d ", c);. I get the following output:

49 50 51 52 53 
10 97 98 99 100 
13 10 49 50 51 
53 13 10 97 98 
100 101 13 10 49

You can see those 10s and 13s shifting through.

Now try adding a second fgetc(f); to eat the line feed and it will work much better. Keep in mind, however, that this only works on files with CRLF line endings. Port it to Linux or Mac and you will have more troubles.

Fred Larson
  • 60,987
  • 18
  • 112
  • 174