用字节和字符串初始化C数组

问题描述:

我想用字节数值和字符串一次初始化一个字节数组。基本上阵列是数据结构的序列化表示等用字节和字符串初始化C数组

struct foo { 
    uint8 param1; 
    uint8 stringLen; 
    const char * string; 
    uint8 param2; 
}; 

尽管API期望字节数组,我有超过没有控制。 API期望数组被静态初始化为sizeof运算符来报告实际大小。我知道可以使用字符串文字或特定字节初始化一个数组,尽管任何初始化数组的尝试都是以字符串文字作为指针地址(这是什么,这里并不令人意外)。

我正在考虑定义我自己的struct并用它初始化数组,但我不相信结构或字符串文字是编译时序列化的。我似乎无法想到这样的语法,我甚至不确定这是否可能。任何输入赞赏。

最后的手段可能是像array[] = "\x66oo"这样的初始化数组,但这只会比简单的array[] = {0x66, 'o', 'o'}略微维护,两种解决方案都需要外部(python?)生成器。

+2

您可以定义结构的初始化的'const'数组,它应该在编译时初始化。但请注意结构填充,请参阅编译器手册,了解如何在没有填充的情况下打包结构。 – 2015-03-03 11:16:35

+1

@JoachimPileborg这是一个好主意,但它不会序列化字符串文字,编译器仍然可以自由地将它们存储在任何地方。一个固定大小的字符数组将会这样做(如果字符串字面大小是固定的)。 – Vagish 2015-03-03 11:32:30

+0

但是,IIUC,真正的问题是C字符串的标准初始化程序是否假定应该附加一个nul结束符? (字符串连接C字符串将允许'char array [] =“a”“\ x05”“Hello”“b”;',但生成的initalizer将是9个字节长而不是8个字节) – joop 2015-03-03 12:19:50

您必须初始化使用这样的功能的字节数组:

uint8 *initByteArray(const struct foo *foo) 
{ 
    unsigned slen = foo->string ? strlen(foo->string) : 0; 
    assert(slen <= 255); 
    uint8 *array = malloc(slen + 3); 
    unsigned i = 0; 
    array[i++] = foo->param1; 
    array[i++] = (uint8)slen; 
    if (slen) { 
     strncpy(&array[i], foo->string, slen); 
     i += slen; 
    } 
    array[i++] = foo->param2; 
    return array; 
} 

如果struct包含大于1(即uint16等)的长度任意整数,那么你还需要考虑它们在编码过程中的排列顺序。

+0

我知道运行时方法来初始化一个数组,虽然API预计该数组是静态的(BSS段)初始化'sizeof'来报告实际大小。对不起,误解,编辑 – friendzis 2015-03-03 11:32:09

+0

@friendzis嗯,这听起来不像一个简单的问题解决的问题... – trojanfoe 2015-03-03 12:35:20

C允许将字符串文字(也在初始化程序中)分解;编译器会为你粘贴它们。

所以,你可以这样做:

char unit1[8] = "\x40" "\x05" "Hello" "\x3e"; 
char unit2[9] = "\x40" "\x06" "World!" "\x3e"; 

char unitBoth[] = "\x40" "\x05" "Hello" "\x3e" 
        "\x40" "\x06" "World!" "\x3e"; 

unitBoth[]阵列没有定义的大小;它只比单独两个数组的总和长一个字节(nul字节)。


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

int main(void) 
{ 
unsigned idx, len; 

printf("Unit1 Size = %zu\n", sizeof unit1); 
for (idx=0; idx < sizeof unit1; idx++) { 
     printf("%u : %02x\n" , idx , 0xff & unit1[idx]); 
     } 

printf("\nUnit2 Size = %zu\n", sizeof unit2); 
for (idx=0; idx < sizeof unit2; idx++) { 
     printf("%u : %02x\n" , idx , 0xff & unit2[idx]); 
     } 

printf("\nUnitBoth Size = %zu\n", sizeof unitBoth); 
for (idx=0; idx < sizeof unitBoth; idx++) { 
     printf("%u : %02x\n" , idx , 0xff & unitBoth[idx]); 
     } 

return 0; 
} 

当然,你可以创建一个程序或脚本生成的定义。 (并将它们包含在您的主程序中,可能位于全局范围内)