【问题标题】:How to initialize a char array without the null terminator?如何在没有空终止符的情况下初始化 char 数组?
【发布时间】:2019-05-13 04:16:01
【问题描述】:

char数组是网络消息的一部分,长度明确,不需要空终止符。

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

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

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

【问题讨论】:

  • 你需要像这样初始化结构变量:- struct Cmd cmd{ {'A','B','C','D'}, 0}; .如果你给“ABCD”,它被认为是字符串文字,并将存储在 const char 指针中,字符串文字以 '\0' 结尾。
  • @sonulohani 不,这不是“需要的”。除了缺少 = 之外,给定的初始化很好。
  • @JensGustedt C 默默跳过空终止符的技巧很危险——我认为这是一个语言缺陷。因此,提供{'A','B','C','D'} 初始化程序是一种很好的做法:它是自记录代码,表明程序员意识到缺少空终止,但它也允许编译器/静态分析器在代码的其他地方发出警告,当字符串文字初始值设定项会产生一个不以 null 结尾的字符串。
  • @Lundin “需要”和“良好做法”不是一回事。
  • @JensGustedt 您写道初始化很好。但事实并非如此,因为它包含一个潜在的微妙错误。

标签: c arrays string c11 null-terminated


【解决方案1】:

如果char 数组的大小与初始值设定项中的字符数相同,则忽略终止空字符。所以cmd 不会有空终止符。

C11标准(n1570)中的相关部分是6.7.9/14

字符类型的数组可以由字符串文字或 UTF-8 字符串文字初始化,可选用大括号括起来。字符串文字的连续字节(包括终止空字符如果有空间或如果数组大小未知)初始化数组的元素。

还有声明:

struct Cmd cmd { "ABCD" , 0 };

应该是:

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

【讨论】:

  • 请注意,这是另一个领域,C 和 C++ 对事物的工作方式有不同的看法。 C++11 (ISO/IEC 14882:2012) §8.5 初始化器,§8.5.2 字符数组,¶2:初始化器的数量不得超过数组元素的数量。 [ 示例:char cv[4] = "asdf"; // error 格式不正确,因为隐含的尾随 '\0' 没有空格。 —结束示例]
  • 这是否意味着 C++ 在这个问题上与 C 不同?
  • @fluter:是的。在 C++ 中,它是格式错误的。意思是,它不是一个有效的程序。(根据语法规则、可诊断语义规则和一个定义规则构建的程序)
猜你喜欢
  • 2014-01-08
  • 1970-01-01
  • 2013-01-23
  • 1970-01-01
  • 2013-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-23
  • 1970-01-01
相关资源
最近更新 更多