在大小为 10 的 char 数组中输入超过 10 个字符的字符串并输出时,它会显示整个数组而不是前 10 个数组.为什
On inputting a string of more than 10 characters in a char array of size 10 and outputting it, it shows the whole array instead of the first 10. Why?
#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"而不是您输入的整个内容,但它正在执行后者。
欢迎来到未定义的行为领域。 目前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;
这是合法的C++17 代码不会在 C++20 中编译p
因为 不是数组。 您可以在此处查看有关此更改的论文: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++中,数组和指针是可以互换的。
char* a;
char b[123];
// these two call the same function.
cin>>a;
cin>>b;
流运算符>>
不知道您在 char* 指向的任何地方分配了多少存储空间,它只是开始写入直到完成。
现在想象一下,当你遇到这样的案例时会发生什么
char foo[2];
bool bar = false;
cin>>foo;
if (bar)
{
...
}
foo
和bar
在堆栈上彼此相邻。 当cin>>
写过foo
结束时,它会踩踏所有为bar
保留的内存。
如果您听说过"堆栈缓冲区溢出"攻击,这就是他们正在谈论的事情,顺便说一下(我认为(stackoverflow.com 它的名字。 充分覆盖堆栈上的缓冲区以将坏事写入堆栈,例如更改函数将返回到的位置(到同一溢出的不同部分(,以及您可能不希望计算机执行的一堆指令。
- 指向指向字符数组的指针数组的指针
- 比较字符数组
- 如何使用Crypto++并为RSA返回可打印的字节/字符数组
- 使用无符号字符数组有效存储内存
- 按字符值访问int数组
- 错误:字符数组的初始值设定项太多
- 对字符数组中的元素执行逐位操作
- C++,在int数组中输入字符串或字符会输出0,而不是ascii或error
- C++ 无法在字符数组中使用 for 循环打印字母模式
- 如何在 C++ 中从文件中读取字符数组(带有一些空格)
- 移动二维数组中的字符
- C++ 传递二维字符数组
- 无法在 C++ 中输入字符数组
- C++ 带结构的数组字符
- 数组字符包含量超出预期
- 读取文件并添加到数组字符
- 如何在Qt中更改或替换数组字符
- 为什么编译器不在参数中传递数组字符 *arr[] 的大小?
- 井字棋数组字符错误
- 分割数组字符