Ввод после cin.getline () не удается? - PullRequest
0 голосов
/ 27 октября 2010

Я новичок в программировании.В моем учебнике проблема заключалась в том, чтобы написать программу, которая запрашивает у пользователя количество осадков в течение трех месяцев и вычисляет среднее значение.

Я использовал функцию 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 ]

2 голосов
/ 27 октября 2010

Что происходит, 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 ГБ. Это не относится к простым примерам и упражнениям.

1 голос
/ 27 октября 2010

Это потому, что getline считывает до указанного вами размера (минус 1) и оставляет оставшиеся символы в потоке.Когда вы используете (>>) для извлечения осадков, так как в потоке есть нечисловые символы, ошибки cin.Вы должны учитывать это.

...