Antithesis
Antithesis

Reputation: 337

Deserializing a string in C

I've data being sent in the following format

1 2 5
1 3 6
1 4 9

I'm deserializing them using the following function

 void deserialize(RV** arr, char* msg){
        int idx = 0;
        char* line = strtok(msg, "\n");
        RV rv;
        rv.server1 = atoi(strtok(line, " "));
        rv.server2 = atoi(strtok(NULL, " "));
        rv.weight = atoi(strtok(NULL, " "));
        memcpy(arr[idx], &rv, sizeof(rv));
        idx++;

        while (strtok(NULL, "\n") != NULL){
            //printf("%s\n", line);
            RV rv;
            rv.server1 = atoi(strtok(NULL, " "));
            rv.server2 = atoi(strtok(NULL, " "));
            rv.weight = atoi(strtok(NULL, " "));
            memcpy(arr[idx], &rv, sizeof(rv));
            idx++;
        }

    }

This returns the first line correctly, but the rest are all 0

1 2 5
0 0 0
0 0 0

What am I doing wrong. Any help appreciated.

Upvotes: 1

Views: 191

Answers (1)

Some programmer dude
Some programmer dude

Reputation: 409442

One of the problems you are having is that the strtok function is not reentrant, which means you can't use it to tokenize two different strings. If you have strtok_s you could use it, or you could use simple sscanf parsing on each line.

Another problem is that you don't get the new line in the loop.


You could easily replace your code with something like this:

int deserialize(RV** arr, char* msg)
{
    char *line = strtok(msg, "\n");
    int idx = 0;

    do
    {
        sscanf(line, "%d %d %d", &arr[idx]->server1, &arr[idx]->server2, &arr[idx]->weight);
        ++idx;
    } while ((line = strtok(NULL, "\n")) != NULL);

    return idx;  // Return the number of lines we parsed
}

This assumes that there is at least one line (ending with a newline) in the message. Also note that I wrote the code of the top of my head, I haven't tested it.

Upvotes: 4

Related Questions