为什么会这样呢?使用cin读取小于给定输入的字符数组
Why does this work? Using cin to read to a char array smaller than given input
我正在阅读c++ Primer Plus(第6版),我在第4章看到了一些示例代码,我有一个问题:
清单4.2 strings.cpp
// strings.cpp -- storing strings in an array
#include <iostream>
#include <cstring> // for the strlen() function
int main()
{
using namespace std;
const int Size = 15;
char name1[Size]; // empty array
char name2[Size] = "C++owboy"; // initialized array
// NOTE: some implementations may require the static keyword
// to initialize the array name2
cout << "Howdy! I'm " << name2;
cout << "! What's your name?n";
cin >> name1;
cout << "Well, " << name1 << ", your name has ";
cout << strlen(name1) << " letters and is storedn";
cout << "in an array of " << sizeof(name1) << " bytes.n";
cout << "Your initial is " << name1[0] << ".n";
name2[3] = ' '; // set to null character
cout << "Here are the first 3 characters of my name: ";
cout << name2 << endl;
return 0;
}
代码本身不会引起任何混淆,但是我一直在运行它,并且对某个场景感到困惑。
name1被初始化为长度为15个元素的数组-我认为这应该保持长度为14个字符的字符串是对的吗?结束字符应该保留给字符串结束符,对吧?
如果我输入我的名字为HowCanIPossiblyFitThisEntireStringIn?,我得到以下输出:
你好!我是c++ owboy !你叫什么名字?
HowCanIPossiblyFitThisEntireStringIn吗?
HowCanIPossiblyFitThisEntireStringIn ?,你的名字有37个字母,存储在
在一个15字节的数组中
你的首字母是h
这是我名字的前三个字符:c++
我输入的整个名称是如何存储的?如果我分步执行代码,在cin读取到name1之后,Visual Studio告诉我它包含元素0 - 14,最后一个是字符'y' ("HowCanIPossibly…)。我可以从这里假设输入的任何额外数据都被截断并丢失了,但显然不是这样,因为下面的cout成功地将整个名称写到了控制台。
出于好奇,谁能告诉我这里发生了什么事?为了记录,我使用的是Visual Studio 2012 Express。
您正在写入超出数组的边界。c++标准没有说这应该是一个错误;它说这是未定义的行为。这意味着任何事情都有可能发生,包括看起来工作正常。简单地说,你的代码没有良好定义的行为,所以你不应该相信它能工作。
我们可以想象为什么它可能工作。前15个字符可以很好地放入数组中:
|H|o|w|C|a|n|I|P|o|s|s|i|b|l|y|F|i|t|T|h|i|s|E|n|t|i|r|e|S|t|r|i|n|g|I|n|?|...
^ ^
| These characters fit |
in the array
其余字符将被写入以下内存位置。现在,请记住,用于终止c风格字符串的null字符被定义为具有全0位的表示。现在,如果包含?
的位置后面的位置全部为0位,则字符串将以空结束。
但事实是,这是未定义的。它恰好起作用了。不幸的是,这是最可怕的错误类型,因为它似乎可以工作很长一段时间,直到有一天你开始接到非常非常生气的客户的电话。
您可以使用istream::get
与缓冲区和缓冲区的大小:
cin.get(name1, Size);
正如其他人所指出的,使用std::string
:
std::string name1;
cin >> name;
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 2D数组来自文本输入,中间有空格
- 如何使用 < 和 > 命令获取 c++ 中的输入和输出?
- 检查输入是否不是整数或数字
- 正在尝试了解输入验证循环
- 读取文件并输入到矢量中
- C++如何通过用户输入删除列表元素
- 用c++从输入文件中读取另一行
- 读取文件的最后一行并输入到链接列表时出错
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 如何使用用户输入在C++中正确填充2D数组
- C++MySQL C api用户输入行
- 输入到文件并输出到另一个文件,并将流文件传递给函数
- 用户定义函数中的指针和输入
- 压缩算法(例如gzip、zip或snappy)的输出肯定小于输入吗
- C++-返回向量中最大元素的最有效方法小于给定的输入
- C++用户输入的小于10的数字之和
- 使用两个函数在c++中显示小于或等于输入的素数
- 为什么会这样呢?使用cin读取小于给定输入的字符数组