我是编程新手。在我的教科书中,问题在于它编写了一个程序,要求用户提供三个月的降雨量并计算平均值。
我使用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;
}
答案 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;)提取降雨量时,由于流中存在非数字字符,因此会出现错误。你需要考虑到这一点。