使用sscanf()解析Json消息

时间:2016-02-19 10:52:16

标签: c json udp scanf

我的应用程序通过JSon从对象坐标收到UDP消息,如下所示:

{
    "FRAME1": {
        "X": "-0.885498",
        "Y": "-0.205078",
        "Z": "0.628174"
    },
    "FRAME2": {
        "X": "1.70898",
        "Y": "-5.67627",
        "Z": "0.305176"
    },
    "ID": "DEVICE9",
    "TS": "7.9900"
}

我需要读取FRAME1FRAME2的坐标(每帧的X,Y,Z值)。 Json消息存储在char[] msg中。我使用以下代码行,得到FRAME1的坐标:

char Xc[32], Yc[32], Zc[32];
sscanf (msg,
        "{\"X\":\"%s\",\"Y\":\"%s\",\"Z\":\"%s\"}",
        Xc, Yc, Zc);

我将printf的存储值显示为:

printf("X coordinate is: %s\n" , Xc);

然而输出很奇怪:

X coordinate is: |-

sscanf()提供的格式有什么问题?

2 个答案:

答案 0 :(得分:1)

带有%n说明符和sscanf

strcmp可用于解析字符串。 %n捕获扫描中使用的字符数。

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

int main()
{
    int index = 0;
    int offset = 0;
    char sub[300] = "";
    char Xc[32] = "";
    char Yc[32] = "";
    char Zc[32] = "";
    char msg[] = {
    "{\n\
    \"FRAME1\": {\n\
        \"X\": \"-0.885498\",\n\
        \"Y\": \"-0.205078\",\n\
        \"Z\": \"0.628174\"\n\
    },\n\
    \"FRAME2\": {\n\
        \"X\": \"1.70898\",\n\
        \"Y\": \"-5.67627\",\n\
        \"Z\": \"0.305176\"\n\
        },\n\
        \"ID\": \"DEVICE9\",\n\
        \"TS\": \"7.9900\"\n\
    }\n"
    };

    offset = 0;
    while ( ( sscanf ( msg + offset, "%299s%n", sub, &index)) == 1) {
        offset += index;
        if ( strcmp (sub, "\"X\":" ) == 0) {
            if ( ( sscanf ( msg + offset, "%31s%n", Xc, &index)) == 1) {
                offset += index;
                printf ( "Xc is %s\n", Xc);
            }
        }
        if ( strcmp (sub, "\"Y\":" ) == 0) {
            if ( ( sscanf ( msg + offset, "%31s%n", Yc, &index)) == 1) {
                offset += index;
                printf ( "Yc is %s\n", Yc);
            }
        }
        if ( strcmp (sub, "\"Z\":" ) == 0) {
            if ( ( sscanf ( msg + offset, "%31s%n", Zc, &index)) == 1) {
                offset += index;
                printf ( "Zc is %s\n", Zc);
            }
        }
    }

    return 0;
}

坐标的上述sscanf将包括引号。这可以用来删除引号

if ( ( sscanf ( msg + offset, " \"%31[^\"]%*s%n", Xc, &index)) == 1) {

答案 1 :(得分:0)

也许您可以尝试使用strtok()代替冒号或其他东西使用冒号?不确定它是否会让你的生活变得更轻松,但我知道strtok()通常建议使用* scanf()系列函数。