стандартный поток ввода cin не запрашивает ввод

1 #include<iostream>
2 using namespace std;
3
4 int main()
5 {
6     const double yen_to_euro=0.007215;
7     const double euro_to_dollar=1.12;
8     char currency;
9     double x;
10
11     while(currency!='q')
12     {
13         cout << "enter currency and unit(y , e, or d)";
14         cin >> x >>currency;
15
16         switch(currency){
17
18             case 'y':
19                 cout <<"euro:"<< x*yen_to_euro<<" dollar:"<<x*yen_to_euro*euro_to_dollar<<'\n';
20                 break;
21             case 'e':
22                 cout <<"yen:"<< (x*(1.0/yen_to_euro))<<" dollar:"<<(x*euro_to_dollar)<<'\n';
23                 break;
24             case 'd':
25                 cout <<" yen:"<< x*(1.0/yen_to_euro)*(1.0/euro_to_dollar)<<" euro:"<<x*(1.0/euro_to_dollar)<<'\n';
26                 break;
27             case 'q':
28                 currency='q';
29                 break;
30             default:
31                 cout << "invalid";
32                 break;
33
34         }
35
36     }
37
38
39 }
~

Предполагаемая функция приведенного выше кода заключается в преобразовании выбранной валюты (y для японской иены, e для евро и d для доллара США) в другие валюты.

Например, если я хочу конвертировать в 12 японских иен, я бы ввел:

12y

который тогда программа выведет

евро: 0,08658 доллар: 0,0969696

Однако, если бы я ввел 12e, я бы получил бесконечный цикл. Двойная проверка кода, похоже, нет никаких логических ошибок.
Тем не менее, я чувствую, что источник проблемы связан с cin в строке 14, потому что если я возьму сумму x и тип валюты отдельно, как это:

cin>> x;
cin>> currency;

Код работает нормально, но мне нужно ввести сумму, затем нажать Enter, а затем нажать символ, который представляет тип валюты. Есть ли способ просто ввести все в одну строку, без пробелов?

Кроме того, почему он так себя ведет? Такое необычное поведение прохождения бесконечного цикла происходит только тогда, когда я ввожу e для евро и q для выхода.

0

Решение

12e интерпретируется как начало числа с плавающей запятой, такого как 12e03. Но конец отсутствует, поэтому ваш поток помещен в ошибку (failbit). Это состояние вызывает сбой всех последующих входных данных, пока состояние сбоя не будет очищено.

Вы могли бы иметь внутренний цикл, который проверяет такие ошибки форматирования:

while (...) {
...
while ( (cin >> x >> currency).fail() && !cin.eof()) { // loops as long as there's input and it's invalid
cout << "invalid format";
cin.clear();
}
if (cin.eof())  // if there's no longer input stop looping
break;
...
}

живое демо

Обратите внимание, что вы должны инициализировать currency к чему-то отличному от ‘q’, если вы хотите убедиться, что ваш цикл выполняется при любых обстоятельствах.

Кстати, если вы введете 12 e (с пробелом), 12 будет интерпретироваться как число и будет переведено в x и e в валюту, как вы ожидаете.

0

Другие решения

Как объясняется другими ответами, 12е относится к научному обозначению чисел с плавающей точкой и, следовательно, currency не хранит «е».

Чтобы получить ввод в одну строку без пробела, вы должны использовать std::getline а затем проанализировать входную строку.

Поскольку вы знаете, что последний символ всегда указывает на валюту, передние символы можно преобразовать в число с помощью std::stoi,

0

замещать cin >> x >>currency;
с

    try{
std::string myLine;
std::getline (std::cin, myLine); // store line into myLine.
currency = myLine.back(); // get last character from line.
myLine.pop_back(); // remove last character from myLine.
x = std::stod(myLine); // try to conver the rest of the string to a double.
}
catch (...) {
//The user typed in something invalid.
currency= 'i';
}

Кроме того, убедитесь, что #include <string>

Обратите внимание, что это решение предполагает, что вы используете C11.

0
По вопросам рекламы [email protected]