【问题标题】:Character arrays declared sequentially overlapping声明顺序重叠的字符数组
【发布时间】:2020-02-10 06:22:50
【问题描述】:

我试图声明两个字符数组,一个接一个。当我这样做时,数组似乎相互重叠。

#include <iostream>

int main(){
    char cmnd[2] = {'l', 's'};
    char flags[1] = {'a'};
    std::cout << "cmnd array: " << cmnd << std::endl;
    std::cout << "flags array: " << flags << std::endl;
}

这段代码的输出就变成了:

cmnd array: ls
flags array: als

根据输出我的标志数组应该只包含{'a'}实际上包含{'a','l','s'}
为什么会出现这种情况?提前感谢您对此问题的任何见解。

【问题讨论】:

  • 您的 cmnd 和 flags 数组本身没有问题。 cmnd 实际上是一个包含 2 个字符的数组,而 flags 确实是一个包含 1 个字符的数组。 “错误”是您对“std::cout

标签: c++ c++11 c++14 c++17


【解决方案1】:

在 C++ 中,所有纯 char 字符串实际上都称为 null-terminated 字节字符串。

这个空终止符告诉所有处理此类字符串的函数,字符串在哪里结束。如果字符串缺少空终止符,它们将超出范围,您将拥有undefined behavior

如果你想将一个字符数组用作字符串,你需要确保它们包含一个空终止符。在您的情况下,这非常简单:初始化时不要指定数组的大小并使用文字字符串:

char cmnd[] = "ls";
char flags[] = "a";

现在cmnd 将是一个由三个 字符组成的数组,并初始化为包含'l''s' 和空终止符'\0'。同样flags 将是两个字符的数组,初始化为'a''\0'

【讨论】:

    【解决方案2】:

    std::cout 将字符数组视为字符串,但您的数组都不是以 NULL 结尾的,但 cout 会继续运行,直到找到 NULL 字符。看起来您的 flags 数组紧接在内存中的 cmnd 数组之前,而 0 出现在紧跟 cmnd 数组的内存位置中。

    如果要将它们视为std::cout 的字符串,请在每个数组的末尾添加一个空字符,即'\0' 或仅0。如果没有,请更改将它们传递给cout 的方式。

    【讨论】:

    • 它应该是0(或等效的'\0'),而不是NULL。后者可能是nullptr,它不能用作charNULL 应该只用作空指针常量,即使这样,自 C++11 以来它也被 nullptr 取代。
    • @walnut 你说得对,我不应该在那里使用 NULL,我指的是 null ('\0') 字符。
    猜你喜欢
    • 2023-04-06
    • 1970-01-01
    • 2012-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多