【问题标题】:Input after cin.getline() fails?cin.getline() 失败后的输入?
【发布时间】:2010-10-27 01:45:46
【问题描述】:

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

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

【问题讨论】:

  • 你需要定义“haywire”。
  • 您可以通过说明 (a) 您的预期,(b) 实际发生的事情,以及 (c) 与您的预期不符的原因来帮助解释“失控”。
  • 失控是程序开始出现异常和不可预测的行为。程序应该计算输入数字的平均值并显示出来;但是,如果输入的输入大于定义的数组,则不会这样做。相反,它会显示一个包含大约一百个有效数字的大数字,每次运行程序都会变化。
  • 双精度数字实际上并没有那么多有效数字,但它们可以有非常高的量级。 :)
  • 我确定这是个玩笑,但我对这个主题太无知而无法理解 :-( 但这就是我学习的原因 :-) FWIW 我实际上数了一下,只有 70 位数显示了

标签: c++ user-input getline


【解决方案1】:

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 的线路。对于简单的示例和练习,情况并非如此。

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 谢谢!因此,即使 cin.getline() 将在比我的数组大小小 1 时停止读取,剩余的字符仍留在键盘缓冲区中并导致程序出错。对吗?
    • 酷,谢谢。人们在这里反应很快。希望有一天我能成为提供答案的人:-)
    猜你喜欢
    • 2014-04-07
    • 1970-01-01
    • 1970-01-01
    • 2018-10-20
    • 2013-06-30
    • 1970-01-01
    • 2014-11-25
    • 1970-01-01
    • 2012-04-29
    相关资源
    最近更新 更多