C语言AT指令参数解析核心实现

江屿
江屿
发布时间:2026-10-14 | 5人浏览过
原创

本文详细介绍如何利用C语言解析标准的AT指令格式(如 AT+REG[admin][2][MAC地址])。核心在于提取方括号内的参数,支持最多三个参数,单个参数限制为20字节以内,并能正确处理缺括号、超长及多余参数等异常情况。

结果与目标

解析类似 AT+REG[admin][2][00:0C:29:AA:0B:A7] 的AT指令,从字符串中提取方括号 [] 内包裹的有效参数值。解析器需满足以下约束:

  • 每个参数被一对 [ 和 ] 包围。
  • 默认单个参数大小不超过 20 字节。
  • 最多解析三个参数,超出返回错误。
  • 指令结尾必须为空字符 '\0' 或换行符 '\n'。
  • 若出现语法错误(如缺少右括号 ]),需给出明确报错。

准备条件

操作需要 C 语言的编译环境以及基础的字符串处理能力。我们需要定义一个结构体来承载解析出的字符串数据,并使用标准库函数进行内存初始化和子串查找。

第1步:定义数据结构

目的:创建用于存储解析结果的容器。

动作:定义 parameters_t 结构体,包含三个长度为20字节的字符数组,分别对应第一、第二、第三个参数。初始化时必须清空内存以防止残留垃圾数据。

第2步:解析第一个参数

目的:验证并提取 AT 指令后的第一个括号内容。

入口:当前输入字符串指针。

动作:

  1. 检查开头:如果首字符为空 '\0' 或换行 '\n',说明无参数,直接返回 0。
  2. 查找左括号:检查是否以 '[' 开始,若不是则报错并返回 -1(错误码)。
  3. 查找右括号:使用 strstr 寻找紧随其后的 ']'。若找不到,判定为格式错误。
  4. 长度校验:计算参数实际长度,若大于等于 20 字节,拒绝解析。
  5. 复制参数:使用 strncpy 将提取到的内容存入结构体的 str1 字段。

第3步:解析第二个参数(可选)

目的:在成功解析第一个参数后,尝试获取第二个参数。

入口:更新后的字符串指针(跳过第一个参数的结束位置)。

动作:

  1. 判断结束:如果当前指针指向 '\0' 或 '\n',说明仅有一个参数,返回 1。
  2. 格式校验:重复第一步的逻辑,验证 '[' 存在且能找到配对的 ']'。
  3. 长度校验与复制:同样限制在 20 字节内,存入 str2。

第4步:解析第三个参数(可选)

目的:获取最后可能的一个参数。

入口:更新后的字符串指针。

动作:

  1. 判断结束:若此时已到达字符串末尾,说明只有两个参数,返回 2。
  2. 格式校验:验证括号配对完整性。
  3. 长度校验与复制:存入 str3。

第5步:最终状态检查

目的:确保指令没有尾随的非法字符。

动作:指针移动至最后一个参数结束后,再次检查后续字符。如果不是 '\0' 或 '\n',则判定为“参数过多”或格式混乱,返回 -1。所有步骤正常完成则返回 3。

代码实现细节

完整的核心解析逻辑如下,重点展示了如何通过指针移动遍历字符串并完成参数截断:

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

// 保存参数的结构体
typedef struct parameters {
    char str1[20]; // 第一个参数
    char str2[20]; // 第二个参数
    char str3[20]; // 第三个参数
} parameters_t;

/***** 获取参数 **********************************************/
// 返回值为获取参数的个数, -1表示指令错误
int Getparams(char* data, parameters_t* pparam) {
    int len = 0;
    memset(pparam, 0, sizeof(parameters_t));

    // --- 第一个参数 ---
    if(0 == *data || '\n' == *data) {
        _ERROR("no parameter!");
        return 0;
    }
    if(strncmp(data, "[", 1)) {
        _ERROR("first parameter err: can't find '['");
        return -1;
    }
    data += 1;
    if(!strstr(data, "]")) {
        _ERROR("first parameter err: can't find ']'");
        return -1;
    }
    len = strstr(data, "]") - data;
    if(len >= 20) {
        _ERROR("param one is too long!");
        return -1;
    }
    strncpy(pparam->str1, data, len);

    // --- 第二个参数 ---
    data += (len + 1);
    if(0 == *data || '\n' == *data) {
        return 1;
    }
    if(strncmp(data, "[", 1)) {
        _ERROR("second parameter err: can't find '['");
        return -1;
    }
    data += 1;
    if(!strstr(data, "]")) {
        _ERROR("second parameter err: can't find ']'"); 
        return -1;
    }
    len = strstr(data, "]") - data;
    if(len >= 20) {
        _ERROR("param two is too long!");
        return -1;
    } 
    strncpy(pparam->str2, data, len);

    // --- 第三个参数 ---
    data += (len + 1);
    if(0 == *data || '\n' == *data) {
        return 2;
    }
    if(strncmp(data, "[", 1)) {
        _ERROR("third parameter err: can't find '['");
        return -1;
    }
    data += 1;
    if(!strstr(data, "]")) {
        _ERROR("third parameter err: can't find ']'"); 
        return -1;
    }
    len = strstr(data, "]") - data;
    if(len >= 20) {
        _ERROR("param three is too long!");
        return -1;
    } 
    strncpy(pparam->str3, data, len);

    data += (len + 1);
    if(0 != *data && '\n' != *data) {
        _ERROR("too much parameter!");
        return -1;
    } 
    
    return 3;
}

异常处理说明

该实现包含了一些关键的边界条件检查。例如,对于输入 AT+ABC[ha12ha[1122] 这种嵌套或缺失右括号的错误写法,解析器在寻找 ']' 时若无法匹配,会立即终止并报错,防止了缓冲区溢出或非法数据的读取。

以上就是基于C语言指令的深入分析与参数实现的详细内容,更多关于AT指令解析的资料请关注本站其它相关文章!

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表