jlee jlee - 23 days ago 5
C Question

Having trouble using strtok on stdin

I'm having an unusually hard time reading from std, splitting on spaces, then putting those tokens into an array. (Ignore the allocation of 80 bytes, this is just temporary for testing)

char* inputLine = (char*)malloc(80);
char* commands[80];
char* input;
int i;
fgets(inputLine, 80, stdin);
input = strtok(inputLine, " \n");
for (i=0; input != NULL; i++) {
memcpy(commands[i], input, sizeof(input));
input = strtok(NULL, " \n");
}


With input of

command1 command2 command3


The output should be

commands[0] = "command1"
commands[1] = "command2"
commands[2] = "command3"


However, the output I get is

commands[0] = "command1"
commands[1] = ""
commands[2] = "command3"


When stepping through the debugger, I can see that commands[0] and commands[1] get populated correctly. However, when the last memcpy gets executed, it assigns command[2] and erases command[1].

My experience with C is very limited, I appreciate someone pointing out my stupid mistake!

Answer

It appears that you have not allocated memory to store the commands. You have only allocated an array of pointers, so your behavior is actually undefined. The fix is to allocate memory and initialize it.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(){
    char* inputLine = (char*)malloc(80);
    char* commands[80];
    char* input;
    int i;
    int numCommands = 0;
    fgets(inputLine, 80, stdin);
    input = strtok(inputLine, " \n");
    for (i=0; input != NULL; i++) {
        numCommands++;
        commands[i] = malloc(strlen(input) + 1);
        strncpy(commands[i], input, strlen(input));
        input = strtok(NULL, " \n");
    }

    for (i = 0; i < numCommands; i++) {
        puts(commands[i]);
    }
}
Comments