2017-02-01 2 views
0

вот мое решение простой проблемы моего учебника. Внутри этого я пытаюсь использовать входной поток, чтобы сначала обнаружить нечисловый вход, а затем проверить, запущен ли он с помощью '|' символ завершения программы:Использование потока ввода после того, как что-то не так было введено в C++

int main() 
{ 
    double n1, n2; 
    char Finisher; 
    while (true) { 
     std::cout << "Enter number 1:\n"; 
     if (std::cin >> n1) {} 
     else { 
      std::cin >> Finisher; 
      if (Finisher == '|') break; //Condition that must lead to program termination. 
      std::cin.clear(); 
      std::cin.ignore(40000,'\n'); //40000: only a big number 
     } 
     std::cout << "Enter number 2:\n"; 
     if (std::cin >> n2) {} 
     else { 
      std::cin >> Finisher; 
      if (Finisher == '|') break; 
      std::cin.clear(); 
      std::cin.ignore(40000, '\n'); 
     } 

     if (n1 < n2) { 
      std::cout << "The smaller value is: " << n1 << " \nThe larger value is: " << n2 << '\n'; 
      if ((n1 - n2) < 1.0/100 && (n1 - n2) > -1.0/100) { 
       std::cout << "The values are almost equal\n"; 
      } 
     } 
     else if(n1>n2){ 
      std::cout << "The smaller value is: " << n2 << " \nThe larger value is: " << n1 << '\n'; 
      if ((n1 - n2) < 1.0/100 && (n1 - n2) > -1.0/100) { 
       std::cout << "The values are almost equal\n"; 
      } 
     } 
     else { std::cout << "both values are equal\n"; } 
    } 
    return 0; 
} 

Проблема заключается в том, что моя переменная символ «финишера», кажется, бесполезно, и любой нечисловой вход (вид) потеряется! и в него вводится другой фиксированный символ, независимо от того, что я ввел, в моем случае это всегда так: enter image description here Что случилось ?! Спасибо.

+0

Просто нит-кик. Возможно, вы захотите сделать больше * «DRY - не повторяйте себя» *. – WhiZTiM

+0

Почему бы не прочитать строку (или, возможно, [целую строку] (http://en.cppreference.com/w/cpp/string/basic_string/getline)), проверьте, является ли первый символ [цифрой] (http: //en.cppreference.com/w/cpp/string/byte/isdigit), а затем попытайтесь [преобразовать строку в целое число] (http://en.cppreference.com/w/cpp/string/basic_string/stol). Если не цифра, то проверьте на '' | '', и если не найдено, просто отбросьте ввод. –

+0

@Yuriy lvaskevych Очистить его, чтобы изменить состояние отказа std :: cin, так что он снова может принимать новые введенные входы, и я использую ignore для удаления любых предыдущих входов. (их имена (clear & ignore) немного отличаются от того, что они делают) –

ответ

1

Перемещение ясный() вверх, кажется, работает:

if (std::cin >> n1) {} 
    else { 
     std::cin.clear(); 
     std::cin >> Finisher; 
     if (Finisher == '|') break; //Condition that must lead to program termination. 
     std::cin.ignore(40000,'\n'); //40000: only a big number 
    } 
0

Проблема заключается в том, что как только для чтения не удается, cin находится в состоянии, когда он не сможет никогда больше ничего читать до вас clear это , Вы должны позвонить cin.clear(); перед чтением в Finisher.

Конечно, это все еще помещает вас в положение, в котором вы читаете отдельный символ для Finisher. Было бы более элегантно читать в одном токене, а затем проверить, является ли это номером или символом канала.

#include <cstdlib> 
#include <iostream> 
#include <sstream> 
#include <stdexcept> 
#include <string> 

typedef double number; 

number parse_number() { 

    static std::string in; 
    static std::istringstream stream; 
    number ret; 

    std::cin >> in; 
    stream.clear(); 
    stream.str(in); 

    if (stream >> ret) 
     return ret; 

    if (in.front() == '|') 
     std::exit(0); 

    std::ostringstream error; 
    error << "Could not parse token, \"" << in << ".\""; 
    throw std::runtime_error(error); 

} 

int main() { 

    while (true) { 

     const number n1 = parse_number(); 
     const number n2 = parse_number(); 

     // Do stuff with the numbers. 

    } 

}