我很好奇为什么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;
}
Run Code Online (Sandbox Code Playgroud)
现在如果输入是12 34 cat输出则12 34 cat
是预期的.
但是如果输入是cat 23 dog输出的话0 87 Mary.
这就是我认为这是意料之外的原因:
cin >> a应该失败,因为cat无法转换为整数.然而,a取而代之的是我认为是垃圾值.
现在由于输入的第二个数字是整数23,所以cin >> b必须成功.然而,这种操作似乎失败了,并且b不像发生的那样继续保持其原始价值a.
同样,getline无法将字符串<space>dog放入字符串中s
,该字符串将继续保留其原始值Mary.
我的问题如下.
某些cin操作的失败是否要求使用运算符或函数的所有
后续cin操作失败.>>getline
为什么第一次cin操作的失败改变了值,a
而初始值b和s?没有变化?
某些cin操作的失败是否要求使用>>运算符或getline函数的所有后续cin操作失败.
是.直到你清除错误cin.clear().此外,当提取失败时,字符将保留在缓冲区中,因此如果您尝试再次读取相同类型,则会再次失败.
为什么第一个cin操作失败会改变a的值而b和s的初始值没有变化?
因为(从C++ 11开始),它被定义为在从(先前)有效流中提取失败的情况下将值更改为0.在C++ 11之前,它将保持不变.对于处于错误状态的流,操作不执行任何操作,这就是原因b并且s不变.
- 某些cin操作的失败是否要求使用>>运算符或getline函数的所有后续cin操作失败.
是.您的代码希望以该顺序读取输入值
cin >> a ; // 1st integer value
cin >> b ; // 2nd integer value
getline(cin,s); // string value
Run Code Online (Sandbox Code Playgroud)
给它一个输入
cat 23 dog
Run Code Online (Sandbox Code Playgroud)
在尝试读取第一个值时导致设置fail()状态,并且以下调用都不会成功.cinintoperator>>()
cin >> a应该失败,因为cat无法转换为整数.然而,a取而代之的是我认为是垃圾值.
它没有垃圾价值,但定义明确,请参阅下面的参考引文.
现在由于输入的第二个数字是整数23,所以
cin >> b必须成功.然而,这种操作似乎失败了,并且b不像发生的那样继续保持其原始价值a.
没有这个假设是错误的,正如此处提到cin的fail()状态,并且根本没有解析进一步的输入.
您必须clear()在每次调用后operator>>()调用,以确保输入将通过解析:
cin >> a ; // 1st integer value
cin.clear();
cin >> b ; // 2nd integer value
cin.clear();
getline(cin,s); // string value
Run Code Online (Sandbox Code Playgroud)
- 为什么第一个cin操作失败会改变a的值而b和s的初始值没有变化?
因为参考std::basic_istream::operator>>()说
"如果提取失败,则将零写入值并
failbit设置.如果提取导致值太大或太小而无法拟合值,std::numeric_limits<T>::max()或者std::numeric_limits<T>::min()写入并failbit设置标志.(自C++ 11起) "