C query string parsing

前端 未结 1 704
遥遥无期
遥遥无期 2020-12-20 08:49

I have the following query string

address=1234&port=1234&username=1234&password=1234&gamename=1234&square=1234&LOGIN=LOGIN

相关标签:
1条回答
  • 2020-12-20 08:56

    When parsing a sting that may contain an empty-field between delimiters, strtok cannot be used, because strtok will treat any number of sequential delimiters as a single delimiter.

    So in your case, if the variable=values fields may also contain an empty-field between the '&' delimiters, you must use strsep, or other functions such as strcspn, strpbrk or simply strchr and a couple of pointers to work your way down the string.

    The strsep function is a BSD function and may not be included with your C library. GNU includes strsep and it was envisioned as a replacement for strtok simply because strtok cannot handle empty-fields.

    (If you do not have strsep available, you will simply need to keep a start and end pointer and use a function like strchr to locate each occurrence of '&' setting the end pointer to one before the delimiter and then obtaining the var=value information from the characters between start and end pointer, then updating both to point one past the delimiter and repeating.)

    Here, you can use strsep with a delimiter of "&\n" to locate each '&' (the '\n' char included presuming the line was read from a file with a line-oriented input function such as fgets or POSIX getline). You can then simply call strtok to parse the var=value text from each token returned by strsep using "=" as the delimiter (the '\n' having already been removed from the last token when parsing with strsep)

    An example inserting a specific empty-field for handling between "...gamename=1234&&square=1234...", could be as follows:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main (void) {
    
        char array[] =  "address=1234&port=1234&username=1234&password=1234"
                        "&gamename=1234&&square=1234&LOGIN=LOGIN",
            *query = strdup (array),  /* duplicate array, &array is not char** */
            *tokens = query,
            *p = query;
    
        while ((p = strsep (&tokens, "&\n"))) {
            char *var = strtok (p, "="),
                 *val = NULL;
            if (var && (val = strtok (NULL, "=")))
                printf ("%-8s    %s\n", var, val);
            else
                fputs ("<empty field>\n", stderr);
        }
    
        free (query);
    }
    

    (note: strsep takes a char** parameter as its first argument and will modify the argument to point one past the delimiter, so you must preserve a reference to the start of the original allocated string (query above)).

    Example Use/Output

    $ ./bin/strsep_query
    address     1234
    port        1234
    username    1234
    password    1234
    gamename    1234
    <empty field>
    square      1234
    LOGIN       LOGIN
    

    (note: the conversion of "1234" to a numeric value has been left to you)

    Look things over and let me know if you have further questions.

    0 讨论(0)
提交回复
热议问题