0

I'm trying to split user input into an array of strings in C. It works 40% of the time. Sometimes, users will input a string and all will be as predicted. Sometimes, the same string will be inputted, and the content of the arrays will be different. I cannot figure out why.

void run_game(struct board *made_board){
    char **user_command;

    user_command = (char **)malloc(sizeof(char *)*4);
    user_command = split_string(user_command);

    printf("Input1: %s\n", user_command[0]);
    printf("Input2: %s\n", user_command[1]);
    printf("Input3: %s\n", user_command[2]);
}

char** split_string(char **user_input){
    char user_command[10];
    char *word;
    int word_counter = 0;

    fgets(user_command, 10, stdin);
    while(strlen(user_command)>9){
        fgets(user_command, 10, stdin);
    }

    word = strtok (user_command," ");
    user_input[word_counter] = word;
    word_counter++;

    while (word != NULL){
        word = strtok (NULL, " ");
        user_input[word_counter] = word;
        word_counter++;
    }
    return user_input;
}

Input1, Input2 and Input3 sometimes will be what comes in from fgets, sometimes it will be random characters. That's two different behaviour for the exact same input.

Haziq Nordin
  • 195
  • 1
  • 3
  • 10
  • Also see [Why do I get a mysterious crash or “segmentation fault” when I copy data to an uninitialized pointer?](http://stackoverflow.com/questions/37549594/why-do-i-get-a-mysterious-crash-or-segmentation-fault-when-i-copy-data-to-an-u). – Lundin Jun 29 '16 at 13:48

1 Answers1

0

The problem is that you are inserting pointers to memory inside a local array command into user_input without making a proper copy. This leads to undefined behavior.

When you do this

word = strtok (user_command," ");

word gets a pointer that points inside char user_command[10]. If you want to insert it into user_input[word_counter], duplicate the string.

If strdup is available, and you don't mind using it, a simple solution would be

user_input[word_counter] = strdup(word); // You need to do it in two places

You can also use your own strdup as described in this Q&A.

Community
  • 1
  • 1
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523