cin.getline()失败后输入?

时间:2010-10-27 01:45:46

标签: c++ user-input getline

我是编程新手。在我的教科书中,问题在于它编写了一个程序,要求用户提供三个月的降雨量并计算平均值。

我使用cin.getline()函数将用户输入读入数组。该文本指出不必担心使用cin.getline()函数对数组进行溢出。但是,如果我输入的字符串大于数组,我的程序会变得混乱。为什么会这样?

#include "stdafx.h"
#include <iostream>
#include <iomanip>
using namespace std;

int main()
{
 const int SIZE = 10;
 char month1[SIZE], month2[SIZE], month3[SIZE];
 double rain1, rain2, rain3, average;

 cout << "Enter the name of the first month:  ";
 cin.getline(month1,SIZE);
 cout << "Enter the rainfall for " << month1 << ":  ";
 cin  >> rain1;
 cin.ignore();


 cout << "Enter the name of the second month:  ";
 cin.getline(month2,SIZE);
 cout << "Enter the rainfall for " << month2 << ":  " ;
 cin  >> rain2;
 cin.ignore();

 cout << "Enter the name of the third month:  ";
 cin.getline(month3,SIZE);
 cout << "Enter the rainfall for " << month3 << ":  ";
 cin  >> rain3;
 cin.ignore();

 average = (rain1 + rain2 + rain3)/3;

 cout << fixed << showpoint << setprecision(2) 
   << "The average rainfall for " << month1 << ", " << month2 
   << ", and " << month3 << " is " << average << " inches\n\n";


 return 0;
}

2 个答案:

答案 0 :(得分:2)

istream :: getline会读取限制,然后停止。您不会通过读取换行来检查它是否已完成,因此当您稍后再读取该行时,该流的输入包含无法转换为double的字符:这会使流处于失败状态。

因为您不检查输入(进入double)是否成功,所以使用该值会导致未定义的行为。如果您改为初始化double(以避免UB),您会发现它的值没有改变。

虽然有时你想使用istream :: getline,但这不是其中之一:使用std :: string和std :: getline:

std::string month1;
double rain1;

getline(std::cin, month1);
if (std::cin >> rain1) {
  // input succeeded, use month1 and rain1
}
else {
  // input of either month1 or rain1 failed; recover or bail (e.g. return 1;)
}

使用istream :: getline的唯一原因是你必须限制可能的恶意输入消耗过多的内存;例如10 GB线路。对于简单的示例和练习,情况并非如此。

答案 1 :(得分:1)

这是因为getline将读取您指定的大小(减1),并在流中保留剩余的字符。当您使用(&gt;&gt;)提取降雨量时,由于流中存在非数字字符,因此会出现错误。你需要考虑到这一点。