2
votes

I'm trying to read a file (map.txt) with fopen() and fgetc(), but I'm getting an infinite loop and strange characters as output. I've tried different conditions, different possibilities, and the loop is always infinite, as if EOF did not exist.

I want to create a map-tile basic system with text files (Allegro), and to do so I need to learn how to READ them. So I'm trying to simply read the file and print its contents, character by character.

void TileSystem() {

    theBitmap = al_load_bitmap("image.png"); // Ignore it.  

    float tileX = 0.0; // Ignore it.    
    float tileY = 0.0; // Ignore it.    
    float tileXFactor = 0.0; // Ignore it.  
    float tileYFactor = 0.0; // Ignore it.  

    al_draw_bitmap( theBitmap, 0, 0, 0 ); // Ignore it. 

    FILE *map;
    map = fopen( "map.txt", "r");

    int loopCondition = 1;
    int chars;

    while ( loopCondition == 1 && ( chars = fgetc( map ) != EOF ) ) {
            putchar( chars );
        }
}

The content of map.txt is:

1
2
3
4
5
6
7
8
9

And what I get of output is an infinite loop of:

???????????????????????????????????????????????????
???????????????????????????????????????????????????
???????????????????????????????????????????????????...

But what I see on terminal is:

EOF BUG

Well, I just need to read all the chars, and the compiler needs to recognize the end of the file correctly.

4
Today's tip: Parenthesize everything! Relying on esoteric rules of operator precedence is a recipe for tears. - Carl Norum
BTW: the loopcondition is loop-invariant. - wildplasser

4 Answers

4
votes
chars = fgetc( map ) != EOF

should be

(chars = fgetc(map) ) != EOF

This is a complete working example:

#include <stdio.h>

int main() {
  FILE *fp = fopen("test.c","rt");
  int c;
  while ( (c=fgetc(fp))!=EOF) {
    putchar(c);
  }
}
1
votes

This line:

chars = fgetc( map ) != EOF

Is getting executed like this:

chars = (fgetc( map ) != EOF)

So you should add parentheses like this:

(chars = fgetc( map )) != EOF
1
votes
while ( loopCondition == 1 && ( chars = fgetc( map ) != EOF ) ) {

doesn't look right... Have you tried:

while ( loopCondition == 1 && ( ( chars = fgetc( map ) ) != EOF ) ) {
1
votes
chars = fgetc( map ) != EOF 

!= has higher precedence than =, you probably wanted to do something like this instead: (chars = fgetc( map )) != EOF