问题记录|c语言json库解析字符串操作,应该先解析再判断

引言:最近在做一个mqtt的项目用到cJson库的解析遇到了一些问题

我的需求:

 由于每次服务器端只会来一个指令用udp协议发送到设备端,是一个封装好的了的字符串;格式就像这样子的:

Received:
 {"paras":{"led":true},"service_id":"smokeDetector","command_name":"LED灯"}

sendto ret: 74

里面就一个是重要的对象就是这个            {"led":true}

但是每次来的键可能是bot可能temp不同的建,我需要写几个if来判断他。把值取出来再进行控制设备端的操作。

1.一开始我直接从buf里面取出json然后进行解析,

        发现他那个解析一步然后判断一些有没有这个键值对,然后再操作,可是发现,你先检查了一个没有,然后再检查下一个键值对的时候就出现了段错误。

代码如下:

cJSON *root = cJSON_Parse(buf);
    if (root == NULL)
        {
            printf("Error parsing JSON: %s\n", cJSON_GetErrorPtr());
            continue;
        }

        // 解析并处理具体的指令
        cJSON *paras = cJSON_GetObjectItem(root, "paras");
        if (paras != NULL)
        {
            cJSON *temp = cJSON_GetObjectItem(paras, "temp");
            if (temp != NULL )
             {
                // 假设我们只关心最后一个温度值
                temp_values[MAX_TEMP_VALUES - 1] = temp->valueint;
                printf("收到温度数据咯\n");
            }

            cJSON *led = cJSON_GetObjectItem(paras, "led");
            if (led != NULL && led->type !=0)
            {
                light_button_state = 0; // ON
                control_led(8, 1); // 打开D8灯
                lv_obj_set_style_bg_color(light_button, lv_color_hex(0x007AFF), 0); 
            // 设置按钮背景颜色
                 lv_label_set_text(light_btn_label, "ON");
            }
            else if (led != NULL && led->type == 0) 
            {
                light_button_state = 1; // OFF
                control_led(8, 0); // 关闭D8灯
                lv_obj_set_style_bg_color(light_button, lv_color_hex(0xFFA000), 0); 
            // 设置按钮背景颜色
                lv_label_set_text(light_btn_label, "OFF");
            }

            cJSON *bot = cJSON_GetObjectItem(paras, "bot");
            printf("收到的:%d\n",bot->type);
            if (bot != NULL && bot->type !=0)
            {
                //printf("我进来了收到1了\n");
                flush_button_state = 0; // ON
                control_led(7, 1); // 打开D7灯
                lv_obj_set_style_bg_color(flush_button, lv_color_hex(0x007AFF), 0); 
            // 设置按钮背景颜色
                lv_label_set_text(flush_btn_label, "ON");

            } 
            else if (bot != NULL && bot->type==0)
            {
                flush_button_state = 1; // OFF
                control_led(7, 0); // 关闭D7灯
                lv_obj_set_style_bg_color(flush_button, lv_color_hex(0xFFA000), 0); 
            // 设置按钮背景颜色
                lv_label_set_text(flush_btn_label, "OFF");
            }
            
             cJSON_Delete(root); // 删除 cJSON 对象,释放内存
        }

2.原因

        后面我发现,主要原因是cjson* 这个操作会创建一个结构体,理论上应该是空的(!!!但是里面有一些被初始化的成员)

        cJSON_GetObjectItem(paras, "temp");     这个函数执行后然后没有读取的到想要的数据,返回值是空的,所以整个结构体部分空的,里面有被未初始化的成员。

        但是这个时候,我去执行一个判断,if (temp != NULL )。这个结构体里面有一些成员,if里面的条件当然成立,然后就执行了if里面的语句,  可是这个结构体 里面的valueint是个NULL值。并没有东西;这样时候我再去执行这个操作,去获取里面的值temp->valueint;

  if (led != NULL && led->type !=0)

而且这个if判断,不能这样写

我这个led的json结构体还没确认里面是不是正常,就立刻进去led结构体里面取这个type值就会出现段错误    

    就会触发内存的段错误。

3.解决方法

        我们可以先进行全部的取值出来,然后再去判断,然后再进行操作,就不会触发段错误了;

 if (paras != NULL)
        {


            cJSON *temp = cJSON_GetObjectItem(paras, "temp");
            cJSON *led = cJSON_GetObjectItem(paras, "led");
            cJSON *bot = cJSON_GetObjectItem(paras, "bot");
            if(temp != NULL)
            {
                temp_n=temp->valueint;
                temp_values[MAX_TEMP_VALUES - 1] = temp_n;
                printf("temp里面是:%d\n",temp->valueint);
                lv_label_set_text_fmt(temp_label, "temperature : %d°C", temp_values[MAX_TEMP_VALUES - 1]);
            }

            if (led != NULL)
            {
                led_n=led->type;
                printf("led里面是:%d\n",led->type);
                if (led_n!=0)
                {
                    light_button_state=0;
                    control_led(8, 1); // 打开D8灯
                    lv_obj_set_style_bg_color(light_button, lv_color_hex(0x007AFF), 0); // 设置按钮背景颜色
                    lv_label_set_text(light_btn_label, "ON");
                    /* code */
                }
                else
                {
                    light_button_state=1;
                    control_led(8, 0); // 关闭D8灯
                    lv_obj_set_style_bg_color(light_button, lv_color_hex(0xFFA000), 0); // 设置按钮背景颜色
                    lv_label_set_text(light_btn_label, "OFF");
                }

            }
            if (bot != NULL)
            {
                bot_n=bot->type;
                printf("bot里面是:%d\n",bot->type);
                if (bot_n!=0)
                {
                    flush_button_state = 0; // ON
                    control_led(7, 1); // 打开D7灯
                    lv_obj_set_style_bg_color(flush_button, lv_color_hex(0x007AFF), 0); // 设置按钮背景颜色
                    lv_label_set_text(flush_btn_label, "ON");
                }
                else
                {
                    flush_button_state = 1; // OFF
                    control_led(7, 0); // 关闭D7灯
                    lv_obj_set_style_bg_color(flush_button, lv_color_hex(0xFFA000), 0); // 设置按钮背景颜色
                   lv_label_set_text(flush_btn_label, "OFF");
                }            
            }

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值