如何在C语言中为结构体设置静态数据?附代码示例
结构体初始化与字符数组赋值问题
问题背景
我定义了以下结构体:
typedef struct DeviceState_s { uint32_t Function_Type; uint8_t Left_Trigger;//byte [1]#9 left analog trigger uint8_t Right_Trigger;//byte [2]#10 right analog trigger uint8_t Buttons_1;//byte [3]#11 1----XY(1/Z) ..X and Y are the bits representing the buttons state (1 for unpress 0 for press) the last bit is z if the controller supports it. uint8_t Buttons_2;//byte [4]#12 PR PL PD PU start A B (1/C) PR=pad right same for the rest and the bit marked as one is c if the controller supports it. uint8_t Analog_a1;//byte [5]#13 useless in original controller uint8_t Analog_a2;//byte [6]#14 useless in original controller uint8_t Analog_Y;//byte [7]#15 joystick Y axis movement uint8_t Analog_X;//byte [8]#16 joystick X axis movement } DeviceState; typedef struct DeviceStatus_s { uint32_t Function; uint32_t DeviceID[3]; uint8_t AreaCode; //1 uint8_t ConnectorDirection; //1 char ProductName[30]; char ProductLicense[60]; uint16_t StandbyPower; //2 uint16_t MaxPower; //2 } DeviceStatus; typedef struct Status_FPacket_s { PacketHeader Header; //4 DeviceStatus Status; //112 } Status_FPacket; static Status_FPacket Status_Packet;
之后我会填充这些结构体,但其中Status部分内容固定,无需每次填充。我尝试在结构体类型定义里直接初始化Status成员,但这种方法无效:
typedef struct Status_FPacket_s { PacketHeader Header; //4 DeviceStatus Status //112 = { .Function = FUNC_CONTROLLER, .DeviceID[0] = 0xffff06fe, .DeviceID[1] = 0x0000ffff, .DeviceID[2] = 0x00000000, .AreaCode = 0xff, .ConnectorDirection = 0, .ProductName =0, .ProductLicense =0, .StandbyPower = (430>>8) | (430<<8), .MaxPower = (500>>8) | (500<<8), }; } Status_FPacket;
现有解决方案(修正语法后)
根据AbeMonk的建议,我改为定义一个静态的DeviceStatus变量并初始化,之后直接赋值给Status_Packet.Status:
typedef struct DeviceStatus_s { uint32_t Function; uint32_t DeviceID[3]; uint8_t AreaCode; //1 uint8_t ConnectorDirection; //1 char ProductName[30]; char ProductLicense[60]; uint16_t StandbyPower; //2 uint16_t MaxPower; //2 } DeviceStatus; static DeviceStatus controllerStatus = { .Function=FUNC_CONTROLLER, .DeviceID[0]= 0xffff06fe, .DeviceID[1]= 0x0000ffff, .DeviceID[2] = 0x00000000, .AreaCode = 0xff, .ConnectorDirection = 0, .ProductName = "Your Product Name", .ProductLicense = "Your License Content", .StandbyPower = (430>>8) | (430<<8), .MaxPower = (500>>8) | (500<<8), };
使用时直接赋值:
Status_Packet.Status = controllerStatus;
疑问:不用strncpy如何给字符数组赋值
我目前用strncpy设置字符串:
strncpy(Status_Packet.Status.ProductName, "text here", sizeof(Status_Packet.Status.ProductName));
想了解不使用strncpy时的赋值方式。
可行的替代方式
1. 初始化时直接赋值
仅适用于变量定义阶段,可以直接用字符串字面量初始化字符数组,编译器会自动补全字符串终止符'\0':
static DeviceStatus controllerStatus = { // 其他成员初始化... .ProductName = "My Game Controller", .ProductLicense = "MIT License - 2024", // 其他成员初始化... };
注意:这种方式不能用于后续的赋值语句(比如controllerStatus.ProductName = "New Name";是非法的,因为字符数组名是常量指针,不能直接被赋值)。
2. 使用memcpy手动补终止符
如果需要在运行时动态赋值,可以用memcpy配合字符串长度控制,手动添加终止符避免乱码:
const char* newName = "Updated Controller Name"; size_t nameLen = strlen(newName); // 确保不超出数组容量,留位置给'\0' if (nameLen >= sizeof(Status_Packet.Status.ProductName)) { nameLen = sizeof(Status_Packet.Status.ProductName) - 1; } memcpy(Status_Packet.Status.ProductName, newName, nameLen); Status_Packet.Status.ProductName[nameLen] = '\0'; // 手动添加终止符
3. 逐个字符赋值(不推荐)
可以手动遍历字符串逐个赋值,最后添加终止符,这种方式繁琐,仅适合特殊场景:
const char* newLicense = "Sample Commercial License"; int i = 0; while (newLicense[i] != '\0' && i < sizeof(Status_Packet.Status.ProductLicense)-1) { Status_Packet.Status.ProductLicense[i] = newLicense[i]; i++; } Status_Packet.Status.ProductLicense[i] = '\0';
内容的提问来源于stack exchange,提问作者user2144480
相关产品推荐
相关产品推荐

