使用 sscanf() 解析 Json 消息

Parsing Json message with sscanf()

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

{
    "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() 提供的格式有什么问题?

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

带有 %n 说明符的

sscanfstrcmp 可用于解析字符串。 %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) {