[英]char* truncated when assigned as struct member
我有一个具有以下typedef的结构。
typedef struct {
short cmdLength;
char cmdRequest[126];
} cmdRequest_t;
然后我在主程序中有以下代码。
char *command = "d tcpip\0";
printf("command: %s\n", command);
size_t cmdLen = strlen(command);
printf("size: %zu\n", cmdLen);
cmdRequest_t cmdRequest = {(short) cmdLen, *command};
printf("size: %hi\n", cmdRequest.cmdLength);
printf("command: %s\n", cmdRequest.cmdRequest);
但是,我的输出如下。
command: d tcpip
size: 7
size: 7
command: d
大小仍然正确,但是由于某种原因该命令被截断为一个字母。 知道为什么会这样吗?
发生的是...
cmdRequest_t cmdRequest = {(short)cmdLen, *command};
这将初始化成员cmdRequest
的cmdRequest
作为反引用command
,或者换句话说,你会在字符串中的第一个字符结束。 在那之后实际上没有零太容易了,以至于printf()
不起作用。 如果您更改了一些不相关的内容,那么您可能会完美地拥有这样的输出...
command: d%$232!>~11cCV224
mysh: program received SIGSEGV, Segmentation fault
改为这样做...
#include <string.h>
cmdRequest_t cmdRequest;
cmdRequest.cmdLength = (short)cmdLen;
strncpy(cmdRequest.cmdRequest, command, sizeof(cmdRequest.cmdRequest) - 1);
使用strcpy而不是普通分配
将取消引用的char指针分配给数组时,仅读取第一个char
command
是指向char
的指针。
它使用字符串常量初始化,这意味着它是指向该字符串的第一个字符(即'd'
)的指针。
如果取消引用指向char
的指针,结果将得到它指向的单个char
,因此*command
值为'd'
。
您正在初始化一个结构,该结构在C语言中是“聚合类型”,而该结构的第二个成员是一个数组,它也是一个“聚合类型”。
C90在第6.5.7节“初始化”中说
否则,具有聚合类型的对象的初始值设定项应是用大括号括起来的聚合成员的初始值设定项列表,并以递增的下标或成员顺序编写; 具有联合类型的对象的初始化程序应为联合的第一个成员的括号括起来的初始化程序。
如果聚合包含的成员是聚合或联合,或者联合的第一个成员是聚合或联合,则规则将递归应用于子聚合或包含的联合。 如果子集合或包含的并集的初始化程序以左括号开头,则该括号括起来的初始化程序及其匹配的右括号将初始化子集合的成员或所包含的并集的第一个成员。 否则,仅使用列表中足够的初始化程序来考虑子集合的成员或所包含的并集的第一个成员; 剩下的所有初始化程序都将初始化当前子聚合或所包含的并集所属的聚合的下一个成员。
结构的初始化程序包含在大括号中,因此该初始化程序中的初始化程序按顺序初始化结构成员cmdLength
和cmdRequest
,以便将cmdLength
初始化为cmdlen
并将cmdRequest
初始化为'd'
。
cmdRequest
是一个聚合,但其初始化程序不在大括号中,因此“仅使用列表中足够的初始化程序来考虑子cmdRequest[0]
的成员”,因此cmdRequest[0]
初始化为'd'
。
如果你想要初始化cmdRequest
到其第一件被指向数组command
,你必须与strcpy的做到这一点:
cmdRequest_t cmdRequest;
cmdRequest.cmdLen = (short) cmdLen;
strcpy(cmdRequest.cmdRequest, command);
抱歉,但这就是使用字符串不是真实数据类型的语言时得到的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.