C语言中字符数组的高效解析

Parsing char array efficiently in C

本文关键字:高效 数组 语言 字符      更新时间:2023-10-16

我想高效地解析char数组。在c中,正确的方法是什么?我是c编程的新手。请引导我。

数据为32字节。第一个字节是版本,第二个和第三个字节是序列号,依此类推。

void parsepacket(u8_t data[]) {
    u8_t version = data[0];
    u16_t sequence_number = ?;
    u16_t error_status = ?;
    u8_t command_type = ?;
    u8_t attribute_count = ?;
    u8_t pay_load[25] = ?;
}

我想这就是你想要的。。。

void parsepacket(const u8_t data[]) {  //same as u8_t*data
        u8_t version;
        u16_t sequence_number;
        u16_t error_status;
        u8_t command_type;
        u8_t attribute_count;
        u8_t pay_load[25];
        u8_t i =0;
        version = data[i];
        i++;
        sequence_number =(u16_t)(8<<data[i] + data[i+i]);
        i+=2;
        error_status = (u16_t)(8<<data[i] + data[i+i]);
        i+=2;
        attribute_count = data[i];
        i++;
        for(int j=0;j<25;j++)
          pay_load[j] = data[i++];
    }

数组适用于类似的数据类型,例如,您可以使用数据类型为u8_t或u16_t的数组等。在这种情况下,如果您将其作为对结构的引用来传递,例如,那就太好了

typedef struct {
u8_t version;
u16_t sequence_number;
u16_t error_status;
u8_t command_type;
u8_t attribute_count;
u8_t pay_load[25];
..
} data_seq;
void parsepacket(data_seq *input) {
}

data_seq*ptr_dataseq;使用调用

parsepacket(&ptr_dataseq);

假设您不需要制作可移植代码,您可以首先尝试制作一个打包结构,根据定义,它可以删除每个元素相同粒度的填充或对齐。

在gcc中(您可能需要查阅工具链的开发人员手册),它是用完成的

struct __attribute__((__packed__)) foo {
     u8_t data;
     u16_t version;
     ...
     u8_t payload[25];

};

您可能还需要插入sizeof(struct foo) == 32的代码(通过ASSERTING)。这本身对于预处理器来说有点棘手,但却是可行的(另请参阅注释)。

下一个问题是检查体系结构是否允许从非单词边界读取单词。一条线索可能是,c编译器警告要偏离严格的对齐规则,这一点应该认真对待。

一种可能性是对转换进行硬编码,正如这里已经提到的那样。如果这是一个重复出现的模式,那么可能值得构建一个运行时解析器,解析例如

int data(char *input, size_t input_length, const char *fmt_string, void *result)
{
   switch (*fmt_string)
   {
       case '':  break;
       case 'b' : 
          *result = input++; break;
       case 'w' :
          result = align_to(result, sizeof(uint16_t));
          *(uint16_t *)result = get_word(input);
          input+=sizeof(uint16_t); break;
    }
}

它将解析例如字符串"bWWbb25b",其中大写可以选择性地表示字节序。

最有效的方法可能取决于许多因素,例如:

  • 阵列中的字节顺序是否与CCD_ 2中的字节顺序相同
  • 目标机器是否允许字节对齐的16位字
  • 编译器是否支持结构打包方法
  • 您希望代码的可移植性或特定于机器/编译器的程度
  • 无论您需要复制数据还是简单地用覆盖的结构重新解释它(零拷贝)

这些场景中的大多数已经给出了答案。

也就是说,它只有32个字节——这真的需要多高效?如果它在任何情况下都能满足您的性能限制,那么您可能会更好地追求清晰度和可移植性。