在C中反序列化字符串

时间:2015-11-25 12:38:10

标签: c strtok

我以下列格式发送数据

1 2 5
1 3 6
1 4 9

我使用以下函数对它们进行反序列化

 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++;
        }

    }

这会正确返回第一行,但其余的都是0

1 2 5
0 0 0
0 0 0

我做错了什么。任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:4)

您遇到的一个问题是strtok函数不可重入,这意味着您无法使用它来标记两个不同的字符串。如果你有strtok_s可以使用它,或者你可以在每一行使用简单的sscanf解析。

另一个问题是你没有在循环中获得新行。

您可以使用以下内容轻松替换代码:

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
}

这假设消息中至少有一行(以换行符结尾)。另请注意,我编写了我的头顶代码,我还没有测试过。