c++中cin的一个基本行为说明
Clarification on a basic behavior of cin in C++
我很好奇为什么cin
以以下方式表现。我想我可能有对它的行为有一些误解。
考虑这个简单的代码。这段代码要求输入一些输入,所有这些输入都在最后一条语句中打印出来。
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char** argv) {
cout << "Please enter your input: " ;
int a=3, b=87; // initialized to some random integers
string s = "Mary" ; // initialized to a random string
cin >> a ;
cin >> b ;
getline(cin,s);
cout << "You entered the following " << a << " " << b << " " << s << endl;
return 0;
}
现在如果输入是12 34 cat
,输出是12 34 cat
这是意料之中的。
然而,如果输入是cat 23 dog
,输出是0 87 Mary
。
以下是我认为这是出乎意料的原因:
cin >> a
应该失败,因为cat
不能转换为整数。然而,a
被我认为是一个垃圾值所取代。
现在,由于输入的第二个数字是一个整数23,cin >> b
必须成功。然而,这个操作似乎失败了,与a
不同,b
继续保留其原始值。
同样,getline
无法将字符串<space>dog
放入字符串s
中它继续保持其原始值Mary
。
某些
cin
操作失败是否意味着所有操作失败?使用>>
操作符或getline
函数执行cin
的后续操作。为什么第一次
cin
操作失败会改变a
的值而b
和s
的初始值不变。
某个cin操作的失败是否意味着所有cin操作的失败使用>>操作符或getline的后续cin操作函数。
是的。直到您清除错误与cin.clear()
。此外,当提取失败时,字符将留在缓冲区中,因此如果您再次尝试读取相同类型,它将再次失败。
为什么第一个cin操作失败会改变a的值而b和s的初始值是不变的?
因为(从c++ 11开始),它被定义为在从(先前)有效的流中提取失败时将值更改为0。在c++ 11之前,它将保持不变。对于处于错误状态的流,该操作不做任何操作,这就是b
和s
保持不变的原因。
- 使用>>操作符或getline函数时,某些cin操作失败是否会导致后续所有cin操作失败?
是的。您的代码期望按照以下顺序读取输入值
cin >> a ; // 1st integer value
cin >> b ; // 2nd integer value
getline(cin,s); // string value
输入像
cat 23 dog
导致在读取第一个int
值时将fail()
的状态设置为cin
,并且随后的operator>>()
调用都不会成功。
cin >> a
应该失败,因为cat
不能转换为整数。然而,a
被我认为是一个垃圾值所取代。
它不是垃圾值,但定义良好,参见下面的参考引用。
现在,由于输入的第二个数字是一个整数23,
cin >> b
必须成功。然而,这个操作似乎失败了,b
继续保持其原始值,而a
则不同。
不,这个假设是错误的,如前所述,cin
此时处于fail()
状态,并且根本跳过对进一步输入的解析。
您必须在每次调用operator>>()
之后调用clear()
,以确保输入将被解析:
cin >> a ; // 1st integer value
cin.clear();
cin >> b ; // 2nd integer value
cin.clear();
getline(cin,s); // string value
- 为什么第一个cin操作失败改变了a的值,而b和s的初始值不变?
因为std::basic_istream::operator>>()
的引用说
"如果提取失败,将0写入value并设置
failbit
。如果抽取结果值太大或太小而无法匹配值,则写入std::numeric_limits<T>::max()
或std::numeric_limits<T>::min()
并设置failbit
标志。<一口>(因为c++ 11) 一口> "
您应该使用cin.good()
函数或@AndyG所说的简写符号if(cin)
来检查cin
对象的状态。变量a
的类型是int
,那么你怎么能&为什么要输入字符串?因此,它为变量a
提供了意外输出。
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 运行同一解决方案的另一个项目的项目
- 挂起和取消挂起一个文件DLL
- 用C++中的一个变量定义一个常量
- 函数向量_指针有不同的原型,我可以构建一个吗
- 在c++中用vector填充一个简单的动态数组
- 如何在选项卡视图Qt中设置一个新项目,并保存以前的项目
- 预处理器:插入结构名称中的前一个行号
- 我在c++代码中生成了一个运行时#3异常
- 有没有办法我可以在 C++ 中使用 if 语句来说明如果一个字符串不是两个名称的 eqal,它会给出一个输出,ATM i
- 当强调CPP明确说明一个弹性时,我会出现错误
- 如何在C 中编写一个程序,以说明不知道它正在阅读的数据文本文件中包含多少行
- 用于确定一个类是否派生自另一个类的代码说明
- 为什么一个具有多个公共访问说明器标准_layout的类
- 一个数字和字段宽度的格式化输出,C++标准在哪里说明它
- 环境变量在一个char*中,说明如何将其转换为std::字符串
- visualstudio2010-有没有一个列表,说明哪些编译器支持C++标准的哪一部分
- c++中cin的一个基本行为说明