为什么将内存分配给 char 指针不会截断 char 序列

Why allocating memory to a char pointer does not truncate the char sequence

我不明白为什么 char *ptr = new char[7] 不会截断大于 7 个字符的数据输入。还有为什么 eighter char c[7] 会让我输入超过 6 个字符(但在将其赋予超过 6 个字符的字面值时会出错)。

malloc function 做这件事对我来说似乎有点困难,这就是为什么我不想使用它。我宁愿暂时不要使用它。

char qs[7] = "1234567"; //error too many

char qs2[7];
cin >> qs2;             //input 123456789
cout << qs2;            //out same as input, expecting 123456

char *qs3 = new char[7];
cin >> qs3;             //input 123456789
cout << qs3;            //out same as input, expecting 123456

输入流目前只接受一个指针作为参数。因此它无法知道它填充的缓冲区的大小。因此它不知道是否应该截断。读取比缓冲区长的字符串将导致缓冲区溢出,并且程序的行为将是不确定的。别这样。

自 C++20 起,数组操作数通过引用传递,并且该操作确实知道大小并将截断输入。然而,这对 qs3 的情况没有帮助,因为它只是一个指针而不是数组。

相反,您可以使用:

std::cin.get(qs3, 6);
qs3[6] = '[=10=]';

确保读取的字符不超过缓冲区。

或者如果您不想截断输入,那么您可以读入 std::string


Doing it with malloc function seems a little bit to hard for me for a moment, this is why i prefer not to use it.

很好。解决不了你的问题,没必要用,用了也没啥好处。

两个代码片段

char qs2[7];
cin >> qs2;             //input 123456789
cout << qs2;            //out same as input, expecting 123456

char *qs3 = new char[7];
cin >> qs3;             //input 123456789
cout << qs3;            //out same as input, expecting 123456

有未定义的行为。超出分配数组的内存被覆盖。结果可以是任何一种。

考虑以下演示程序。

#include <iostream>

int main() 
{
    char gs1[7] = "123456";
    char gs2[7];
    char gs3[7] = "ABCDEF";

    std::cin >> gs2;

    std::cout << '\n';

    std::cout << gs1 << '\n';
    std::cout << gs2 << '\n';
    std::cout << gs3 << '\n';

    return 0;
}

如果进入

1234567

那么程序输出可能看起来像

123456
1234567

如您所见,未输出字符串 "ABCDEF"。这是在该语句

之后附加到数组 gs2 的终止零 '[=18=]' 的结果
    std::cin >> gs2;

覆盖数组的第一个字符gs3。现在它的内容看起来像

{ '[=15=]', 'B', 'C', 'D', 'F', '[=15=]' }

因此,由于数组的第一个元素是终止零,因此在此语句中输出的是空字符串

    std::cout << gs3 << '\n';

C 字符串以零结尾,这意味着您应该始终分配大小为字符串长度 + 1 的缓冲区。

char qs[7] = "1234567"; //错误太多

在静态分配的缓冲区中,对于编译器来说很明显,您的缓冲区没有 space 用于终止零。这应该是 char qs[8].

在其他两个示例中,运算符都将指向缓冲区的指针作为参数,并且它无法知道它有多大。它只是填充它直到输入结束。您遇到典型的缓冲区溢出情况,幸运的是那里(在缓冲区边界之后)没有重要的东西。