C语言简单数据解析

C语言简单数据解析

​ 在嵌入式开发中通过串口等传输数据通常使用JSON解析,虽然JSON十分强大,但JSON耗费资源太多,数据的打包和解析都比较麻烦。有时我们只是传输一些简单的数据,没必要引入JSON。

​ 下面我将介绍一种简单的数据解析方法,通过编写函数,将字符串解析取得目标数据。

解析字符型数据

函数原型

/**
  * @brief  从一段字符串中解析期望的字符串
  * @param  pBuff: 要解析的字符串地址
  * @param  pLeft: 目标字符串左边的字符串
  * @param  pRight: 目标字符串右边的字符串
  * @param  pRes: 接收字符数据的地址
  * @retval 0:成功 -1:失败
  */
int DataParsingChar(const char *pBuff, const char *pLeft, const char *pRight,char *pRes)
{
    char *pBegin = NULL;
    char *pEnd = NULL;
    pBegin = strstr(pBuff, pLeft);
    pEnd = strstr(pBegin + strlen(pLeft), pRight);
    if (pEnd == NULL || pBegin == NULL || pBegin > pEnd) {
        return -1;
    } else {
        pBegin += strlen(pLeft);
        memcpy(pRes, pBegin, pEnd - pBegin);
        return 0;
    }
}

此函数思想是使用strstr函数找出目标字符串的首尾位置,使用memcpy函数将目标字符串拷贝给接收数据的指针。

测试代码

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

int DataParsingChar(const char *pBuff, const char *pLeft, const char *pRight,char *pRes)
{
    char *pBegin = NULL;
    char *pEnd = NULL;
    pBegin = strstr(pBuff, pLeft);
    pEnd = strstr(pBegin + strlen(pLeft), pRight);
    if (pEnd == NULL || pBegin == NULL || pBegin > pEnd) {
        return -1;
    } else {
        pBegin += strlen(pLeft);
        memcpy(pRes, pBegin, pEnd - pBegin);
        return 0;
    }
}

int main(int argc, char **argv)
{
    /* 原始数据 */
    char *name = "LiHua";
    int age = 20;
    int number = 10086;

    char buff[100] = {0};
    char re_name[10] = {0};
    char re_age[10] = {0};
    char re_number[10] = {0};

    /* 数据打包 */
    sprintf(buff,"name:%s, age:%d, number:%d.",name, age, number);
    
    /* 数据解析 */
    DataParsingChar(buff, "name:", ",", re_name);
    DataParsingChar(buff, "age:", ",", re_age);
    DataParsingChar(buff, "number:", ".", re_number);

    printf("buff : %s\n", buff);
    printf("re_name : %s\n", re_name);
    printf("re_age : %s\n", re_age);
    printf("re_number : %s\n", re_number);

    return 0; 
}

执行结果

buff : name:LiHua, age:20, number:10086.
re_name : LiHua
re_age : 20
re_number : 10086

在测试代码中,使用sprintf将数据打包,通过传入标识符来获取目标数据。

在有些情况,我们希望在字符串中获取整型数据,例如坐标数据等,可以直接拿来运算使用,对上面的解析函数稍加更改,就可以解析整型数据。

解析整型数据

函数原型

/**
  * @brief  从一段字符串中提取出整型数据
  * @param  pBuff: 要解析的字符串地址
  * @param  pLeft: 目标数据左边的字符串
  * @param  pRight: 目标数据右边的字符串
  * @param  pRes: 接收整型数据的地址
  * @retval 0:成功 -1:失败
  */
int DataParsingInt(const char *pBuff, const char *pLeft, const char *pRight, int *pRes)
{
    char *pBegin = NULL;
    char *pEnd = NULL;
    char *pTemp = NULL;
    pBegin = strstr(pBuff, pLeft);
    pEnd = strstr(pBegin + strlen(pLeft), pRight);
    if (pEnd == NULL || pBegin == NULL || pBegin > pEnd) {
        return -1;
    } else {
        pBegin += strlen(pLeft);
        pTemp = (char *)malloc(pEnd - pBegin);
        memcpy(pTemp, pBegin, pEnd - pBegin);
        *pRes = atoi(pTemp);
        free(pTemp);
        return 0;
    }
}

在上面的代码中,增加了atoi函数。此函数经常用于Linux应用开发中,将终端输入的数字型的字符串转换为整型变量(int类型)。在不清楚数字长度的情况下使用malloc分配内存,若传输简短数据可替换成数组,增加代码运行效率。

测试代码

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

int DataParsingInt(const char *pBuff, const char *pLeft, const char *pRight, int *pRes)
{
    char *pBegin = NULL;
    char *pEnd = NULL;
    char *pTemp = NULL;
    pBegin = strstr(pBuff, pLeft);
    pEnd = strstr(pBegin + strlen(pLeft), pRight);
    if (pEnd == NULL || pBegin == NULL || pBegin > pEnd) {
        return -1;
    } else {
        pBegin += strlen(pLeft);
        pTemp = (char *)malloc(pEnd - pBegin);
        memcpy(pTemp, pBegin, pEnd - pBegin);
        *pRes = atoi(pTemp);
        free(pTemp);
        return 0;
    }
}

int main(int argc, char **argv)
{
    /* 原始数据 */
    int left = 123;
    int right = 456;

    char buff[100] = {0};
    int re_left = 0;
    int re_right = 0;

    /* 数据打包 */
    sprintf(buff, "[%d,%d]", left, right);
    
    /* 数据解析 */
    DataParsingInt(buff, "[", ",", &re_left);
    DataParsingInt(buff, ",", "]", &re_right);

    printf("buff : %s\n", buff);
    printf("re_left : %d\n", re_left);
    printf("re_right : %d\n", re_right);
    printf("re_right - re_left = %d\n", re_right - re_left);

    return 0; 
}

执行结果

buff : [123,456]
re_left : 123
re_right : 456
re_right - re_left = 333

在测试代码中,打包了一个坐标字符串,通过函数解析获得整型得目标数据,可以直接进行运算。

  • 6
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值