填充不同的字符数组后,在字符数组的末尾插入垃圾

问题描述 投票:0回答:1
char test1[4];
    test1[0] = '\0';

    test1[0] = char((rand() % 25) + 97);
    test1[1] = char((rand() % 25) + 97);
    test1[2] = char((rand() % 25) + 97);
    test1[3] = char((rand() % 25) + 97);
    test1[4] = '\0';

    cout << test1 << endl;


    char test2[5];
    test2[0] = '\0';

    test2[0] = char((rand() % 25) + 97);
    test2[1] = char((rand() % 25) + 97);
    test2[2] = char((rand() % 25) + 97);
    test2[3] = char((rand() % 25) + 97);
    test2[4] = char((rand() % 25) + 97);

    cout << test1 << endl;

示例输出:

vtcr
vtcrewpcs

uqyr
uqyrvygqx

nqoh
nqohlhuuq

我正在尝试编写一个生成字符串的方法。我想我应该使用 char 数组,因为我计划像任何其他数组一样迭代它,但我一直遇到插入随机垃圾的问题。编写这段代码只是为了尝试解决问题,但我遇到了我不明白的问题。

为什么填充完全不相关的 char 数组会导致第一个数组在打印到命令行时返回垃圾?

我应该使用普通字符串吗?如果是这样,如何用字符填充字符串?

另外,我从未被教导使用字符数组而不是字符串,这是我第一次这样做,我想使用一个,因为填充字符的数组似乎正是我所需要的,但似乎字符数组不就像任何其他数组一样>:(

另外,我这样填写它们是因为这只是一个学习练习。我将使用 for 循环,并且只会随机生成第一个字母。

ALSO ALSO ALSO,这是主要的,其余的看起来像这样:

int main() {
    cout << boolalpha;
    srand(time(NULL));

    ...

    return EXIT_SUCCESS;
}
c++ arrays string char
1个回答
0
投票

您的索引超出了数组的末尾。如果你定义一个有 4 个元素的数组,那么你只能访问索引 0、1、2、3。如果你想要的只是一个指针,那么索引后一位是可以的,但如果你读取或写入该地址是未定义的行为。

将 NULL 终止符写入第一个元素,然后用其他数据覆盖它也是没有意义的。看起来您希望这会执行某种神奇的字符串终止操作,但数组并没有什么神奇之处。

所以,您看到的是未定义的行为。您尝试以 NULL 终止该字符串,但在未被该数组占用的内存中写入了其边界之外的内容。因此,如果您的程序没有立即崩溃,则该内存位置的内容是不确定的。当您尝试输出字符串时,

std::cout
会不断扫描内存寻找 NULL 终止符,在这种情况下直到稍后才找到。

为了让您的代码正常工作,您必须使用更大的数组。至少:

char test1[5];
char test2[6];

// Note that you also need to terminate `test2`, which you did not do.
// Although technically you never output that string, so it wouldn't
// change anything.

我应该使用普通字符串吗?如果是这样,如何用字符填充字符串?

是的。在大多数情况下,只需使用

std::string
,除非您有非常具体的原因需要使用数组。这些原因通常与避免使用动态内存有关。您可以使用
push_back
方法来附加字符:

std::string make_random_string(size_t size)
{
    std::string foo;
    foo.reserve(size);
    for (size_t i = 0; i < 4; i++) {
        foo.push_back('a' + rand() % 26);
    }
    return foo;
}

请注意,

reserve
并不是绝对必要的,但出于礼貌。如果您知道需要多少数据,请务必提前告知。

© www.soinside.com 2019 - 2024. All rights reserved.