用字节和字符串初始化C数组
问题描述:
我想用字节数值和字符串一次初始化一个字节数组。基本上阵列是数据结构的序列化表示等用字节和字符串初始化C数组
struct foo {
uint8 param1;
uint8 stringLen;
const char * string;
uint8 param2;
};
尽管API期望字节数组,我有超过没有控制。 API期望数组被静态初始化为sizeof
运算符来报告实际大小。我知道可以使用字符串文字或特定字节初始化一个数组,尽管任何初始化数组的尝试都是以字符串文字作为指针地址(这是什么,这里并不令人意外)。
我正在考虑定义我自己的struct
并用它初始化数组,但我不相信结构或字符串文字是编译时序列化的。我似乎无法想到这样的语法,我甚至不确定这是否可能。任何输入赞赏。
最后的手段可能是像array[] = "\x66oo"
这样的初始化数组,但这只会比简单的array[] = {0x66, 'o', 'o'}
略微维护,两种解决方案都需要外部(python?)生成器。
答
您必须初始化使用这样的功能的字节数组:
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
等)的长度任意整数,那么你还需要考虑它们在编码过程中的排列顺序。
答
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;
}
当然,你可以创建一个程序或脚本生成的定义。 (并将它们包含在您的主程序中,可能位于全局范围内)
您可以定义结构的初始化的'const'数组,它应该在编译时初始化。但请注意结构填充,请参阅编译器手册,了解如何在没有填充的情况下打包结构。 – 2015-03-03 11:16:35
@JoachimPileborg这是一个好主意,但它不会序列化字符串文字,编译器仍然可以自由地将它们存储在任何地方。一个固定大小的字符数组将会这样做(如果字符串字面大小是固定的)。 – Vagish 2015-03-03 11:32:30
但是,IIUC,真正的问题是C字符串的标准初始化程序是否假定应该附加一个nul结束符? (字符串连接C字符串将允许'char array [] =“a”“\ x05”“Hello”“b”;',但生成的initalizer将是9个字节长而不是8个字节) – joop 2015-03-03 12:19:50