char *在指定为struct成员时被截断

时间:2015-09-16 01:12:08

标签: c pointers struct

我有一个带有以下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

大小仍然正确,但由于某种原因,命令被截断为一个字母。知道为什么会这样吗?

3 个答案:

答案 0 :(得分:4)

会发生什么......

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

答案 1 :(得分:0)

使用strcpy而不是普通赋值

将解除引用的char指针分配给数组时,只读取第一个char

答案 2 :(得分:0)

command是指向char的指针。

它用字符串常量初始化,这意味着它是指向该字符串的第一个字符的指针,即'd'

如果您取消引用指向char的指针,则会得到它所指向的单个char,因此*command会计算为'd'

您正在初始化一个结构,它是C中的“聚合类型”,该结构的第二个成员是一个数组,它也是一个“聚合类型”。

C90在第6.5.7节“初始化”中说。

  

否则,具有聚合类型的对象的初始值设定项应为聚合成员的括号括起的初始值设定项列表,以增加的下标或成员顺序写入;并且具有联合类型的对象的初始化程序应该是联合的第一个成员的大括号括起初始化程序。

     

如果聚合包含聚合或联合的成员,或者联合的第一个成员是聚合或联合,则规则将递归地应用于子聚合或包含的联合。如果子集合或包含的并集的初始值设定项以左括号开头,则由该括号括起的初始值设定项及其匹配的右括号初始化子集合的成员或所包含的并集的第一个成员。否则,只有列表中的足够的初始值设定项用于说明子集合的成员或所包含的并集的第一个成员;任何剩余的初始值设定项都用于初始化当前子聚合或包含的union所属的聚合的下一个成员。

结构的初始化程序用大括号括起来,因此初始化程序中的初始化程序按顺序初始化结构成员cmdLengthcmdRequest,因此它将cmdLength初始化为{{1将cmdlen初始化为cmdRequest

'd'是一个聚合,但它的初始化程序不在大括号中,因此“列表中只有足够的初始值设定项来考虑子聚合的成员”,因此cmdRequest初始化为{ {1}}。

如果要将cmdRequest[0]初始化为'd'指向其第一个成员的数组,则必须使用strcpy:

cmdRequest

很抱歉,但这是使用字符串不是真实数据类型的语言时所得到的....