cparsingscanfuser-input

Parsing with a space (sscanf or strtok)


For some context, my game runs in the terminal and is like a command line type game. At the moment to process commands is does a strcmp() for every single command which isn't really pretty nor efficient. Because of this, I decided I should redo it. I tried looking at other posts and didn't find anything useful. What I'm looking for is for it to save each section of the command. For example:

    //let's just say command = "debug test"
    char part1;
    char part2;

    split via " "

    part1 = "debug"
    part2 = "test"

I tried to use sscanf() but it would just cut down the string. For example let's say I gave it the string "test". It would output: test -> est -> st //and so on


Solution

  • Here's a minimal solution using sscanf():

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define PART_LEN 5
    #define str(s) str2(s)
    #define str2(s) #s
    
    int main() {
        char command[] = "debug test";
        char part1[PART_LEN+1] = "";
        char part2[PART_LEN+1] = "";
        int r = sscanf(command, "%" str(PART_LEN) "s%" str(PART_LEN) "s", part1, part2);
        if(r != 2) {
            // handle partial input
        }
        printf("part=%s part2=%s\n", part1, part2);
    }
    

    The key insights are:

    1. The two parts variables needs to be arrays char [] of appropriate size where sscanf() can store copies of the strings.
    2. Always use a maximum field width when reading strings with scanf()-family of functions.
    3. Handle incomplete input (r != 2). In this case I initialized the two parts to the empty string.

    and here is a similar solution with strtok():

    #include <stdio.h>
    #include <string.h>
    
    #define DELIM " "
    
    int main() {
        char command[] = "debug test";
        char *part1 = strtok(command, DELIM);
        char *part2 = strtok(NULL, DELIM);
        printf("part=%s part2=%s\n", part1 ? part1 : "", part2 ? part2 : "");
    }
    

    The key insights are:

    1. The variable command must be of type char [] and not char * as strtok() modifies the string.
    2. The first call to strtok() expects a string as the first argument, and NULL on subsequent calls.
    3. part1 and/or part2 may be NULL which which case no tokens were found.

    A 3rd option would be to implement a split() function to return an array of strings found. See Split string with delimiters in C