Home > database >  "Segmentation fault: 11" when using fgets in C
"Segmentation fault: 11" when using fgets in C

Time:12-10

I am writing a command line tool in C to control UNDERTALE save files (cuz why not) and I keep getting a segmentation fault whenever I take input from the user.

Here is all my code:

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>

#define KILOBYTE 1024

/* The 'm()' is so i know what line the fault happens on */

void m(void) {
        printf("X");
}

int main(int argc, char**argv) {
    FILE *file;

    if (file = fopen("~/.undersave", "r")) {
        // Do some code that I haven't written yet
    }
    else {
        char path[KILOBYTE] = "";
        printf("It seems that this is your fist time using UNDERSAVE.\nWe just need to go through some quick installation steps.\nWhere do you want your UNDERTALE save folder to be located? >>> ");
        m();
        fgets(path, KILOBYTE, stdin);
        /*
              The fault happens here, when it asks me, 
              i put in the input like normal, but
              when I press enter, I get a fault before
              it prints 'X'
         */
        m();
        mkdir(path, 0777);
        m();
        file = fopen("~/.undersave", "w");
        m();
        fprintf(file, "%s", path);
        m();
        fclose(file);
    }
      
    return 0;
}

CodePudding user response:

Most likely both calls to fopen fail, because on Unix-like systems ~-expansion is a feature of the shell, and isn't applied to a program opening a file directly with fopen or open. If you want to open a file relative to your home directory, either include the full path, or use getenv to read the HOME environment variable and construct the path within your program. Or, better still, make the filename a command-line argument; those arguments are expanded by the shell before your program sees them, so then ~ expansion would just work.

So the fopen for writing returns NULL, which you don't test for (a more serious bug). And you then try to fprintf to a null file pointer, which naturally crashes.

Also, your printf("X") is not a good diagostic, because output to a terminal is usually buffered. The X's won't actually be written to the screen until a new line is printed, or until you try to read from stdin, or some other special conditions occur. So I suspect the program actually crashes later than you think, on the fprintf instead of the fgets. See Why does printf not flush after the call unless a newline is in the format string? and then put fflush(stdout) after the printf in your m() function.

  • Related