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

C语言缓冲区解析问题:如何正确提取多字节长度与文本内容

解决C语言缓冲区解析的长度字段错误问题

嘿,我帮你揪出问题根源啦!你现在遇到的长度值全为0的情况,核心是没有正确拼接16位长度字段的两个字节,另外还有个容易忽略的字符串终止符小问题,咱们一步步来修复:

1. 为啥长度会是0?

看你的缓冲区示例b'\x01\x02\x00\x04\x00\x04aaaabbbb',text1_length对应的是\x00\x04这两个字节,但你当前代码只取了第一个字节buffer[2](也就是0x00),直接转成uint16_t自然就是0了——16位的长度字段得把两个字节组合起来用才行!

2. 正确解析16位长度字段

根据你的示例结果(\x00\x04对应数值4),这里的长度字段是大端字节序(高字节在前,低字节在后),所以要把两个字节按位拼接:

// 把buffer[2](高字节)左移8位,再和buffer[3](低字节)做或运算
uint16_t text1_length = ((uint16_t)buffer[2] << 8) | (uint16_t)buffer[3];
// 同理处理text2_length
uint16_t text2_length = ((uint16_t)buffer[4] << 8) | (uint16_t)buffer[5];

如果你的协议是小端字节序(低字节在前),那就反过来拼接:

uint16_t text1_length = ((uint16_t)buffer[3] << 8) | (uint16_t)buffer[2];

不过从你的示例来看,大端的写法是完全匹配的。

3. 别忘了字符串终止符!

你用malloc分配了text1_length + 1的空间,这一步很对,但memcpy之后没有给字符串加'\0'终止符——C语言里字符串必须以这个字符结尾,不然打印的时候会出现乱码或者未定义行为。所以拷贝完一定要加上:

memcpy(text1, &buffer[6], text1_length);
text1[text1_length] = '\0'; // 手动添加终止符

memcpy(text2, &buffer[6 + text1_length], text2_length);
text2[text2_length] = '\0';

4. 完整的修复代码

我还给你加上了malloc失败的检查(这是写C代码的好习惯,避免空指针崩溃),完整代码如下:

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

#define BUFFER_SIZE 14 // 匹配你的示例缓冲区长度:2个单字节参数 + 2组双字节长度 + 4+4个字符 = 14字节

int main() {
    char buffer[BUFFER_SIZE] = {0x01, 0x02, 0x00, 0x04, 0x00, 0x04, 'a','a','a','a','b','b','b','b'};
    
    uint8_t arg1 = buffer[0];
    uint8_t arg2 = buffer[1];
    
    // 正确解析双字节长度字段
    uint16_t text1_length = ((uint16_t)buffer[2] << 8) | (uint16_t)buffer[3];
    uint16_t text2_length = ((uint16_t)buffer[4] << 8) | (uint16_t)buffer[5];
    
    // 分配内存并检查是否成功
    char* text1 = malloc(text1_length + 1);
    char* text2 = malloc(text2_length + 1);
    if (!text1 || !text2) {
        fprintf(stderr, "内存分配失败!\n");
        return 1;
    }
    
    // 拷贝字符串并添加终止符
    memcpy(text1, &buffer[6], text1_length);
    text1[text1_length] = '\0';
    
    memcpy(text2, &buffer[6 + text1_length], text2_length);
    text2[text2_length] = '\0';
    
    // 测试输出
    printf("arg1: %u\n", arg1);
    printf("arg2: %u\n", arg2);
    printf("text1_length: %u\n", text1_length);
    printf("text2_length: %u\n", text2_length);
    printf("text1: %s\n", text1);
    printf("text2: %s\n", text2);
    
    // 释放内存,避免泄漏
    free(text1);
    free(text2);
    
    return 0;
}

几个额外的小提醒

  • 字节序是关键:一定要和协议文档确认长度字段是大端还是小端,这是多字节字段解析的核心。
  • 缓冲区边界检查:解析前最好先确认缓冲区总长度足够容纳所有字段,避免越界访问导致崩溃。
  • 内存管理:记得用free释放malloc的内存,养成好习惯避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 13:42:40