c++ - 在大小为10的char数组中输入超过10个字符的字符串并输出后,它将显示整个数组而不是前10个。为什么?

标签 c++ string

#include<iostream>
using namespace std;
int main()
{
char d[10];
cout<<"Enter any string which has more than 10 characters in it";
cin>>d;
cout<<"The string you entered is "<<endl;
cout<<d;
    return 0;
}

假设您输入的是“1234567890123”,那么它应该只显示“123456789”,而不是您输入的整个内容,但是它正在执行后者。

最佳答案

欢迎来到未定义的行为 Realm 。目前cin使用以下形式的函数

template< class CharT, class Traits>
basic_istream<CharT,Traits>& operator>>( basic_istream<CharT,Traits>& st, CharT* s );

为了将输入读入数组。由于它使用指针,因此它不知道数组有多大,并且会很高兴地溢出缓冲区,从而导致未定义的行为。

您已经观察到的症状之一是,它会将数据写入您不允许访问的内存中,但是该访问不会导致错误。当您去读取数组的内容时,即使没有,您也可以获得完整的输入。但是,您不能依赖此行为。该程序可能会崩溃或发生其他任何事情。未定义的行为意味着任何结果都可能发生。

从C++ 20开始,使用数组时将不再发生这种情况。该函数的签名更改为
template< class CharT, class Traits, std::size_t N >
basic_istream<CharT,Traits>& operator>>( basic_istream<CharT,Traits>& st, CharT (&s)[N] );

并且由于它通过引用获取数组,因此它知道其大小并可以阻止自身溢出缓冲区。

应当指出,这是一个重大变化。像这样的代码
auto p = new char[100];
std::cin >> std::setw(20) >> p;

由于p不是数组,因此合法的C++ 17代码无法在C++ 20中编译。您可以在此处查看有关此更改的文章:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0487r1.html

如果您切换为使用 std::string ,那么您完全不必担心这一点,因为std::string会随着输入的内容而增长。那会给你
#include<iostream>
#include <string>

int main()
{
    std::string input;
    std::cout << "Enter any string which has more than 10 characters in it";
    std::getline(std::cin, input);
    std::cout << "The string you entered is \n" << input;
    return 0;
}

关于c++ - 在大小为10的char数组中输入超过10个字符的字符串并输出后,它将显示整个数组而不是前10个。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59459317/

相关文章:

string - 在每行中添加连续的数字

string - 如何有效地检查两个字符串之间的 Levenshtein 编辑距离是否为 1

android - 如何设置部分 TextView 可点击

c++ - gcc 是否保证对 volatile 整数的对齐访问是原子的?

C++ 复制构造函数行为

c++ - 使用 Boost::Asio 停止线程服务器循环

c++ - 指针、引用还是智能指针?

c++ - 组成一组容器类并从基访问它们

jQuery 从字符串中提取单词

c - C中的字符串搜索和格式化