0

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

我使用 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;
}
4

2 回答 2

2

发生的情况是 istream::getline 读取到极限,然后停止。您不会通过读取换行符来检查它是否完成,因此当您稍后读取双精度时,流的输入包含无法转换为双精度的字符:这会使流处于失败状态。

因为您不检查输入(到双精度)是否成功,所以使用该值会导致未定义的行为。如果你改为初始化你的 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 的线路。对于简单的示例和练习,情况并非如此。

于 2010-10-27T01:55:02.373 回答
1

这是因为 getline 将读取到您指定的大小(减 1),并将剩余的字符留在流中。当你使用(>>)提取降雨时,由于流中有非数字字符,cin 错误。你需要考虑到这一点。

于 2010-10-27T01:54:20.407 回答