繁体   English   中英

澄清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必须成功。 然而,这种操作似乎失败,并且b继续保持其原有不像发生了什么价值a

类似地, getline无法将字符串<space>dog放入字符串s ,而字符串s继续保留其原始值Mary

我的问题如下。

  1. 某些cin操作的失败是否要求使用>>运算符或getline函数的所有后续cin操作失败。

  2. 为什么第一个cin操作失败会改变a的值而bs的初始值没有变化?

某些cin操作的失败是否要求使用>>运算符或getline函数的所有后续cin操作失败。

是。 直到你用cin.clear()清除错误。 此外,当提取失败时,字符将保留在缓冲区中,因此如果您尝试再次读取相同的类型,它将再次失败。

为什么第一个cin操作失败会改变a的值而b和s的初始值没有变化?

因为(从C ++ 11开始),它被定义为在从(先前)有效流中提取失败的情况下将值更改为0。 在C ++ 11之前,它将保持不变。 对于处于错误状态的流,操作不执行任何操作,这就是bs未更改的原因。

  1. 某些cin操作的失败是否要求使用>>运算符或getline函数的所有后续cin操作失败。

是。 您的代码希望以该顺序读取输入值

cin >> a ; // 1st integer value
cin >> b ; // 2nd integer value
getline(cin,s); // string value

给它一个输入

cat 23 dog

导致在尝试读取第1个int值时在cin上设置fail()状态,并且以下operator>>()调用都不会成功。


cin >> a应该失败,因为cat不能转换成整数。 然而, a被我认为是垃圾值的东西取代了。

它没有垃圾价值,但定义明确,请参阅下面的参考引文。

现在因为输入的第二个数字是整数23,所以cin >> b必须成功。 然而,这种操作似乎失败,并且b继续保持其原有不像发生了什么价值a

没有这个假设是错误的,正如所提到的, cin在此时处于fail()状态,并且根本fail()解析进一步的输入。

你必须在每次operator>>()调用后调用clear() ,以确保输入将被解析:

cin >> a ; // 1st integer value
cin.clear();
cin >> b ; // 2nd integer value
cin.clear();
getline(cin,s); // string value

  1. 为什么第一个cin操作失败会改变a的值而b和s的初始值没有变化?

因为std::basic_istream::operator>>()的引用说明了

“如果提取失败,则将零写入值并设置failbit 。如果提取导致值太大或太小std::numeric_limits<T>::max()适合值,则std::numeric_limits<T>::max()std::numeric_limits<T>::min()写入failbit std::numeric_limits<T>::min()并设置failbit标志。 (自C ++ 11开始)

你应该使用cin.good()函数或简写符号if(cin)如@AndyG所说的来检查cin对象的状态。 变量aint类型,那么你怎么能和为什么输入字符串? 因此,它为变量a提供了意外的输出。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM