Home > Mobile >  Segmentation Fault when reading from file - fgets()
Segmentation Fault when reading from file - fgets()

Time:10-18

Trying to read from a file to use in a small game I've created. I'm using the fgets function. It's returning a Segmentation Fault, not sure why.

The file it's reading, just contains "20 10" in a txt file as this is the map size.

My readfile function is shown below

    if (argc == 2) {
        f = fopen("map.txt", "r");
        if (NULL == f) {
            printf("File cannot be opened.");
        }
        while (fgets(fileRead, 50, f) != NULL) {
            printf("%s", fileRead);
        }
        fclose(f);
    }

The if (argc == 2) can be ignored, this is just to make this section run, as I'm modifying a file so just running this function by satisfying that if statement.

I am fairly new to C, so apologies if I'm missing something minor. Worth noting I'm programming in C89 and using the -Wall -ansi -pedantic compile options, as this is University work and the tutors want us to do C89.

EDIT:

    char userInput, fileRead[50];
    FILE* f;

Declaration of variables.

CodePudding user response:

Assuming that your problem is indeed in your posted code and not somewhere else in the program, then I believe that your problem is caused by the following issue:

After calling fopen, you check the return value of the function immediately afterwards, to verify that it succeeded. However, if it doesn't succeed and it returns NULL, all you do is print an error message to stdout but continue execution as if it succeeded. This will cause fgets to be called with NULL as the stream argument, which will invoke undefined behavior and probably cause your segmentation fault.

In the comments section, you raised the following objection to this explanation:

However it doesn't print the error message anyway and still segmentation faults, so I think the problem isn't here?

This objection of yours is flawed, for the following reason:

When a segmentation fault occurs, execution of the program is immediately halted. The content of the output buffer is not flushed. This means that output can get lost when a segmentation fault happens. This is probably what is happening in your case.

If you want to ensure that the output actually gets printed even in the case of a segmentation fault, you should flush the output buffer by calling fflush( stdout ); immediately after the print statement. Alternatively, you can print to stderr instead of stdout. In constrast to stdout, the stream stderr is unbuffered by default, so that it does not have this problem.

You can test whether my suspicion is correct by changing the line

printf("File cannot be opened.");

to

printf("File cannot be opened.");
fflush( stdout );

or to:

fprintf( stderr, "File cannot be opened." );

If the error message now gets printed, then this probably means that my suspicion was correct.

In any case, I recommend that you change the lines

if (NULL == f) {
    printf("File cannot be opened.");
}

to the following:

if (NULL == f) {
    fprintf( stderr, "File cannot be opened." );
    exit( EXIT_FAILURE );
}

That way, the program will exit immediately if an occur occurs, instead of continuing execution.

Please note that the code posted above requires you to #include <stdlib.h>.

  •  Tags:  
  • c
  • Related