使用cin读取字符数组

4
这是我的代码:
#include <iostream>
using namespace std;

int main(){
    char inp[5], out[4];
    cin >> inp >> out;
    cout << inp << endl;
    cout << out << endl;
    system("pause");
    return 0;
}

当我输入:

12345 6789

它给出结果为:

6789

为什么我无法成功保存由5个字符组成的'inp'数组并导致没有任何显示?第二次输入看起来正常。然而,当我设置out[3]或out[5]时,它似乎能够正确工作?这似乎是由于两个由[5]组成的字符数组后跟[4]引起的问题...


2
你首先向一个5个字符的数组写入11个字符(包括尾随的'\0')。幸运的是,此时没有出现任何问题。然后你又向一个4个字符的数组写入了另外11个字符。在out中没有足够的空间之后,数据溢出到了inp中。修正你的数组大小或限制输入的长度。 - Paul Roub
3个回答

4
我看到您在为inp[5]输入数据时输入了1234567890个字符——这是一个问题,因为imp数组只能存储4个字符和空终止符。当cin >> inp将超过4个字符存储到inp数组中时,会导致数据问题(类似于未定义的行为)。因此,解决方案可以是为数据分配更多的内存,例如:
    #include <iostream>
    using namespace std;

    int main(){
        char inp[15], out[15];  // more memory
        cin >> inp >> out;
        cout << inp << endl;
        cout << out << endl;
        system("pause");
        return 0;
    }

我刚刚发现了一些奇怪的事情。当我将第一个数组的大小设置为5,第二个数组的大小设置为4时,问题才会出现。当我将第二个数组的大小设置为5甚至3时,问题就消失了。我编辑了我的问题,使用了输入12345和6789代替了长数字。 - ken
为了正确存储5个字符的数组,必须至少有6个char项,因为cin >>在用户输入字符后添加'\0'(与scanf函数一样)。 - VolAnd

2

这是因为,在计算机的内存布局中,out[4]排在inp[5]之前。就像这样: out[0],out[1],out[2],out[3],inp[0],inp[1],inp[2],inp[3],inp[4]

所以,当你在out[4]中写入6789时,你将null字符溢出到了inp[0]。因此,inp变成了NULL。


这取决于字节序。 - prehistoricpenguin
你好!这是一个非常古老的问题,正如一些评论和答案所指出的那样,它的代码存在相当多的问题。如果你有兴趣回答一些关于C++的新问题,请查看这个列表https://stackoverflow.com/questions/tagged/c%2b%2b。 - Alexander

2
当你从字符数组中读取数据时,流会一直读取直到遇到空格,流不知道你传递的数组大小,所以会在数组末尾快乐地写入,因此如果你的第一个字符串超过4个字符,你的程序将产生未定义行为(输入后会使用一个额外的字符作为空终止符)。
幸运的是,c++20已经解决了这个问题,流操作符不再接受原始的char指针,只接受数组,并且只会读取size - 1个字符。
即使使用c++20,更好的解决方案也是将类型更改为std::string,它可以接受任意数量的字符并告诉你它包含多少个字符:
#include <iostream>

int main(){
    std::string inp, out;
    std::cin >> inp >> out;
    std::cout << inp << "\n";
    std::cout << out << "\n";
    return 0;
}

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