You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言拆分十六进制数据缓冲区中指令与对应数值的实现方法

C语言十六进制指令缓冲区解析实现

核心处理逻辑

原始缓冲区是按\r\n(对应十六进制值0x0D、0x0A)分隔的ASCII格式指令集,解析按3个阶段执行:

  • 按换行符拆分独立指令行,过滤无效空行
  • 从行首提取连续大写字母(含下划线,适配PARTIAL_CUTTER这类带下划线的指令)作为指令关键字,遇到空格即停止提取
  • 从关键字后续内容中过滤单位(mm)、分隔符(逗号、空格),提取所有数值并和当前指令绑定存储

完整实现代码

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

// 单条指令最大支持参数数量
#define MAX_PARAM_CNT  4
// 指令名最大长度
#define MAX_CMD_LEN    32
// 最大支持指令条数
#define MAX_CMD_NUM    16

typedef struct {
    char cmd_name[MAX_CMD_LEN];
    float params[MAX_PARAM_CNT];
    uint8_t param_cnt;
} CmdStruct;

int main() {
    uint8_t data_buff[] = {0x53, 0x49, 0x5A, 0x45, 0x20, 0x37, 0x36, 0x2E, 0x32,
        0x20, 0x6D, 0x6D, 0x2C, 0x20, 0x35, 0x30, 0x2E, 0x38, 0x20, 0x6D, 0x6D,
        0x0D, 0x0A, 0x42, 0x4C, 0x49, 0x4E, 0x45, 0x20, 0x33, 0x20, 0x6D, 0x6D,
        0x2C, 0x20, 0x30, 0x20, 0x6D, 0x6D, 0x0D, 0x0A, 0x44, 0x49, 0x52, 0x45,
        0x43, 0x54, 0x49, 0x4F, 0x4E, 0x20, 0x30, 0x2C, 0x30, 0x0D, 0x0A, 0x52,
        0x45, 0x46, 0x45, 0x52, 0x45, 0x4E, 0x43, 0x45, 0x20, 0x30, 0x2C, 0x30,
        0x0D, 0x0A, 0x4F, 0x46, 0x46, 0x53, 0x45, 0x54, 0x20, 0x30, 0x20, 0x6D,
        0x6D, 0x0D, 0x0A, 0x53, 0x45, 0x54, 0x20, 0x50, 0x45, 0x45, 0x4C, 0x20,
        0x4F, 0x46, 0x46, 0x0D, 0x0A, 0x53, 0x45, 0x54, 0x20, 0x43, 0x55, 0x54,
        0x54, 0x45, 0x52, 0x20, 0x4F, 0x46, 0x46, 0x0D, 0x0A, 0x53, 0x45, 0x54,
        0x20, 0x50, 0x41, 0x52, 0x54, 0x49, 0x41, 0x4C, 0x5F, 0x43, 0x55, 0x54,
        0x54, 0x45, 0x52, 0x20, 0x4F, 0x46, 0x46, 0x0D, 0x0A};

    CmdStruct cmd_list[MAX_CMD_NUM] = {0};
    uint8_t cmd_total = 0;
    char line_buff[128] = {0};
    uint16_t line_idx = 0;
    uint16_t buff_len = sizeof(data_buff);

    // 按换行拆分每行指令
    for (uint16_t i = 0; i < buff_len; i++) {
        if (data_buff[i] == 0x0D) { // 遇到\r,判定一行结束
            i++; // 跳过后续的\n(0x0A)
            line_buff[line_idx] = '\0';
            if (line_idx > 0 && cmd_total < MAX_CMD_NUM) {
                // 解析当前行内容
                char* p = line_buff;
                uint8_t name_idx = 0;
                // 提取指令名:大写字母/下划线均计入,直到遇到空格停止
                while ((*p >= 'A' && *p <= 'Z') || *p == '_') {
                    cmd_list[cmd_total].cmd_name[name_idx++] = *p++;
                }
                cmd_list[cmd_total].cmd_name[name_idx] = '\0';
                p++; // 跳过指令名后第一个空格

                // 提取数值参数
                char num_buff[16] = {0};
                uint8_t num_idx = 0;
                uint8_t param_cnt = 0;
                while (*p != '\0' && param_cnt < MAX_PARAM_CNT) {
                    if ((*p >= '0' && *p <= '9') || *p == '.') {
                        num_buff[num_idx++] = *p;
                    } else {
                        if (num_idx > 0) {
                            num_buff[num_idx] = '\0';
                            cmd_list[cmd_total].params[param_cnt++] = atof(num_buff);
                            num_idx = 0;
                        }
                    }
                    p++;
                }
                // 处理行尾最后一个参数
                if (num_idx > 0 && param_cnt < MAX_PARAM_CNT) {
                    num_buff[num_idx] = '\0';
                    cmd_list[cmd_total].params[param_cnt++] = atof(num_buff);
                }
                cmd_list[cmd_total].param_cnt = param_cnt;
                cmd_total++;
            }
            // 重置行缓存
            memset(line_buff, 0, sizeof(line_buff));
            line_idx = 0;
        } else {
            line_buff[line_idx++] = data_buff[i];
        }
    }

    // 打印解析结果验证
    for (uint8_t i = 0; i < cmd_total; i++) {
        printf("指令: %s, 参数数量: %u, 参数值: ", cmd_list[i].cmd_name, cmd_list[i].param_cnt);
        for (uint8_t j = 0; j < cmd_list[i].param_cnt; j++) {
            printf("%.1f ", cmd_list[i].params[j]);
        }
        printf("\n");
    }

    getchar();
    return 0;
}

解析输出结果

运行后可得到结构化的指令数据,和预期完全匹配:

指令: SIZE, 参数数量: 2, 参数值: 76.2 50.8 
指令: BLINE, 参数数量: 2, 参数值: 3.0 0.0 
指令: DIRECTION, 参数数量: 2, 参数值: 0.0 0.0 
指令: REFERENCE, 参数数量: 2, 参数值: 0.0 0.0 
指令: OFFSET, 参数数量: 1, 参数值: 0.0 
指令: SET, 参数数量: 0, 参数值: 
指令: SET, 参数数量: 0, 参数值: 
指令: SET, 参数数量: 0, 参数值: 

注:SET类指令(PEEL OFF/CUTTER OFF等)参数为开关状态字符串,无数值参数,因此参数计数为0。如果需要存储字符串参数,可在结构体中新增字符串参数数组成员扩展即可。

内容的提问来源于stack exchange,提问作者Akshay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 00:42:30