Search code examples
carraysfgets

Segmentation fault using fgets()


I am making a basic program, and decided to use functions, and pointers, in the first input I have the choice of typing either, "kitchen", or "upstairs", however when I use fgets() I am getting a segmentation fault, and have no idea why. I tried to print out the string to see if I was getting the correct output, of course due to the segmentation fault it's not happening.

Here's the code:

#include <stdio.h>
#include <string.h>
char one(char *oOne[]);
void two();
void three();

int main() {
    char *oOne[10], oTwo[10], oThree[10]; // Options one, two, and three.
    puts("WELCOME TO ASAD'S ADVENTURE");
    puts("");
    one(oOne);
    return 0;
}

char one(char *oOne[]) {
    puts("You are in a creepy house! Would you like to go \"upstairs\", or into the \"kitchen\"?");

    printf("\n> ");

    if (fgets(*oOne, sizeof *oOne, stdin) == NULL) { // Receiving the input from the user, and removing the \n caused by fgets().
        puts("EOF Occurred");
        return 1;
    }

    *oOne[strcspn(*oOne, "\n")] = 0;
    printf("%s\n", *oOne);
    // puts(*oOne);
}

Here is the output I am receiving:

WELCOME TO ASAD'S ADVENTURE

You are in a creepy house! Would you like to go "upstairs", or into the "kitchen"?

> kitchen
Segmentation fault

How can I fix the segmentation fault?


Solution

  • A character string in C is of type pointer-to-character, e.g.,:

    char *oOne;
    

    Or an array-of-character, if you want to statically allocate your memory:

    char oOne[10];
    

    But not a pointer-to-array-of-character, which is what you have:

    char *oOne[10];
    

    You need:

    char oOne[10];
    

    And then:

    one(oOne);
    

    And then modify your one function with proper types:

    char one(char *oOne)
    {
        if (fgets(oOne, sizeof oOne, stdin) == NULL)
        {
                puts("EOF Occurred");
                return 1;
        }
    
        *(oOne + strcspn(oOne, "\n")) = 0;
    
        printf("%s\n", oOne);
    
    
    }
    

    Although I would pass in an explicit length, rather than using sizeof, because this won't work with dynamically allocated strings:

    car one(char *oOne, int len)
    {
        if (fgets(oOne, len, stdin) == NULL)
        {
                puts("EOF Occurred");
                return 1;
        }
    
        // etc...
    }