澄清C ++中cin的基本行为

时间:2015-05-26 17:31:54

标签: c++ cin

我很好奇为什么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 它继续保留其Mary的原始值。

我的问题如下。

  1. 某些cin操作失败是否导致 all 失败 使用cin运算符或>>函数的后续getline操作。

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

3 个答案:

答案 0 :(得分:9)

  

某些cin操作失败是否导致所有人失败   后续的cin操作使用&gt;&gt;操作员或获取线   功能

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

  

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

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

答案 1 :(得分:5)

  
      
  1. 某些cin操作失败是否要求使用&gt;&gt;所有后续cin操作失败?运算符或getline函数。
  2.   

是。您的代码希望以完全相同的顺序读取输入值

let arr = Array(myDict)
for (ix, (k,v)) in enumerate(arr) {
    println("This key is \(k)")
    if ix < arr.count-1 {
        println("The next key is \(arr[ix+1].0)")
    }
}

给它一个像

这样的输入
cin >> a ; // 1st integer value
cin >> b ; // 2nd integer value
getline(cin,s); // string value

导致在尝试阅读第一个cat 23 dog 值时在fail()上设置cin状态,并且以下任何int调用都不会成功。

  

operator>>()应该失败,因为cin >> a无法转换为整数。但是,cat被我认为是垃圾值的替换。

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

  

现在,由于输入的第二个数字是整数23,a必须成功。然而,这个操作似乎失败了,cin >> b继续保持其原始价值,与b不同。

这个假设没有错,正如前面提到的a处于cin状态,并且根本没有解析进一步的输入。

您必须在每次fail()来电后致电clear(),以确保输入将通过解析:

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

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

  

&#34;如果提取失败,则将零写入值并设置cin >> a ; // 1st integer value cin.clear(); cin >> b ; // 2nd integer value cin.clear(); getline(cin,s); // string value 。如果提取导致值太大或太小而无法拟合,则会写入failbitstd::numeric_limits<T>::max()并设置std::numeric_limits<T>::min()标记。 (自C ++ 11起)&#34;

答案 2 :(得分:2)

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