如何初始化一个没有空终止符的char数组?

7
struct Cmd {
    char cmd[4];
    int arg;
}

struct Cmd cmd { "ABCD" , 0 }; // this would be buffer overflow

如何初始化这个cmd成员的字符数组?而不使用类似于strncpy的函数?


1
你需要像这样初始化结构变量:- struct Cmd cmd{{'A','B','C','D'},0}。如果你输入"ABCD",它会被视为字符串文字并存储在常量字符指针中,字符串文字以'\0'结尾。 - sonulohani
2
@sonulohani 不,这不是“必需的”。 除了缺少 = 之外,给定的初始化是可以的。 - Jens Gustedt
@JensGustedt C语言默默跳过空终止符的技巧是危险的,我认为这是一种语言缺陷。提供{'A','B','C','D'}初始化器因此是一个好的实践:它是自我记录代码,显示程序员意识到缺乏空终止符,但它也允许编译器/静态分析器在代码的其他地方发出警告,当字符串文字初始化器导致未以空终止符结尾的字符串时。 - Lundin
@Lundin,“需要”和“最佳实践”不是同一回事。 - Jens Gustedt
@JensGustedt,你写道初始化没问题。但实际上不是这样的,因为它可能包含一个微妙的错误。 - Lundin
1个回答

15
如果char数组的大小与初始化程序中的字符数相同,则忽略终止的空字符。因此,cmd将不具有空终止符。
C11标准(n1570)中相关的部分是6.7.9/14
“字符类型的数组可以通过字符字符串字面值或UTF-8字符串字面值进行初始化,可选地包含在大括号中。字符串字面值的连续字节(包括终止的空字符如果有空间或如果数组大小未知)初始化数组的元素。”
并且该语句:
struct Cmd cmd { "ABCD" , 0 };

should be:

struct Cmd cmd  = { "ABCD" , 0 };

6
请注意,这是C和C++对于事物应该如何工作具有不同观点的又一个领域。C++11(ISO / IEC 14882:2012)§8.5初始化程序,§8.5.2字符数组,第2段:初始化程序的数量不得超过数组元素的数量。[例: char cv [4] =“ asdf”;//错误 不正确,因为没有为隐含的结尾字符'\0'腾出空间。 ——结束示例] - Jonathan Leffler
这是否意味着在这个问题上C++与C不同? - fluter
3
@fluter:是的,在C++中,这是错误的形式。也就是说,它不是一个有效的程序(根据语法规则、可诊断的语义规则和单一定义规则构建的程序)。 - P.W

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接