2010-10-27 5 views
0

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

Я использовал функцию cin.getline(), чтобы прочитать ввод пользователя в массив. В тексте указано, что нет никакого беспокойства о том, что массив переполняется с помощью функции cin.getline(). Тем не менее, если я ввешу строку, большую, чем массив, моя программа переходит в haywire. Почему это происходит?

#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; 
} 
+1

Вам необходимо определить «haywire». – GManNickG

+2

Вы можете помочь объяснить «haywire», указав (а), что вы ожидаете, (б) что на самом деле произошло, и (c) почему это не соответствовало вашим ожиданиям. –

+0

haywire - это когда программа начинает действовать беспорядочно и непредсказуемо. Программа должна рассчитать среднее число введенных чисел и отобразить это; однако он не делает этого, если вводится ввод, который больше, чем определенный массив. Вместо этого он отображает большое число, содержащее около ста значащих цифр, которое меняется при каждом запуске программы. – knobcreekman

ответ

1

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

+0

Спасибо! так что даже если cin.getline() перестанет читать на одном меньше, чем размер моего массива, оставшиеся символы останутся в буфере клавиатуры и ошибки программы. Это верно? – knobcreekman

+0

@knobcreekman - Да, это правильно. –

+1

круто, спасибо. Люди очень быстро реагируют здесь. Надеюсь, в один прекрасный день я смогу быть тем, кто дает ответы :-) – knobcreekman

2

Что происходит istream :: getline читает до предела, а затем останавливается. Вы не проверяете, закончилось ли это, прочитав новую строку, поэтому, когда вы переходите к чтению двойника позже, вход потока содержит символы, которые не могут преобразовать в double: это помещает поток в состояние сбоя.

Поскольку вы не проверяете, успешно ли введен (в двойном), использование этого значения приводит к неопределенному поведению. Если вы вместо этого инициализируете свой двойной (чтобы избежать UB), вы обнаружите, что его значение не изменилось.

Хотя есть моменты, когда вы хотите использовать IStream :: GetLine, это не один из них: использовать зЬй :: строку и зЬй :: 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 ГБ. Это не относится к простым примерам и упражнениям.

+0

спасибо за объяснение. Я ценю это. – knobcreekman

Смежные вопросы