Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用字节和字符串文字初始化C数组_C_Initialization_String Literals - Fatal编程技术网

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

使用字节和字符串文字初始化C数组,c,initialization,string-literals,C,Initialization,String Literals,我想用一些字节值和字符串文本一次性初始化一个字节数组。本质上,数组是数据结构的序列化表示,如 struct foo { uint8 param1; uint8 stringLen; const char * string; uint8 param2; }; 虽然API需要字节数组,但我无法控制它。API希望数组静态初始化为sizeof操作符,以报告实际大小。我知道可以使用字符串文字或特定字节初始化数组,尽管任何使用字符串文字或特定字节初始化数组的尝试最终都会被视为指针地址(这并

我想用一些字节值和字符串文本一次性初始化一个字节数组。本质上,数组是数据结构的序列化表示,如

struct foo {
  uint8 param1;
  uint8 stringLen;
  const char * string;
  uint8 param2;
};
虽然API需要字节数组,但我无法控制它。API希望数组静态初始化为
sizeof
操作符,以报告实际大小。我知道可以使用字符串文字或特定字节初始化数组,尽管任何使用字符串文字或特定字节初始化数组的尝试最终都会被视为指针地址(这并不奇怪)

我在考虑定义自己的
struct
并用它初始化数组,但我不相信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;
}
uint8*initByteArray(常量结构foo*foo)
{
无符号slen=foo->string?strlen(foo->string):0;
断言(slen参数1;
数组[i++]=(uint8)slen;
如果(slen){
strncpy(&array[i],foo->string,slen);
i+=slen;
}
数组[i++]=foo->param2;
返回数组;
}

如果<代码>结构> /COD>包含长度大于1的整数(即<代码> UTIN 16<代码>等),那么在编码过程中还需要考虑它们的迂回性。

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";

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


#包括
#包括
内部主(空)
{
无符号idx,len;
printf(“单元1大小=%zu\n”,单元1的大小);
对于(idx=0;idx


当然,您可以创建一个程序或脚本来生成定义(并将它们包括在主程序中,可能是在全局范围内)

您可以定义一个初始化的
const
结构数组,它应该在编译时初始化。但要注意结构填充,请参阅编译器手册,了解如何在不填充的情况下打包结构。@JoachimPileborg这是个好主意,但它不会序列化字符串文本,编译器仍然可以自由地任何地方都可以使用。固定大小的字符数组就可以了(如果字符串文字的大小是固定的)。但是,IIUC,真正的问题是C字符串的标准初始化器假定应该附加nul终止符?(C字符串的字符串串联将允许
字符数组[]=“a”“\x05”“Hello”“b”;
,但生成的初始化器的长度将为9字节,而不是预期的8字节)@joop:空终止符的存在不会产生我所知道的任何问题-字符串被严格用作静态字符串,用于人类可读的标识。为什么不在问题中添加API实际期望的内容?我知道初始化数组的运行时方法,尽管API期望数组是静态的(BSS段)初始化为
sizeof
以报告实际大小。抱歉误解,编辑了问题
#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;
}