2012-05-31 2 views
7

Вот кодКак сделать CIN принимать только цифры

double enter_number() 
{ 
    double number; 
    while(1) 
    { 

     cin>>number; 
     if(cin.fail()) 
     { 
      cin.clear(); 
      cin.ignore(numeric_limits<streamsize>::max(), '\n'); 
      cout << "Invalid input " << endl; 
     } 
     else 
     break; 
     cout<<"Try again"<<endl; 
    } 
    return number; 
} 

Моя проблема заключается в том, что когда я ввожу что-то вроде 1х, то 1 берется в качестве входных данных, не замечая характер, что осталось за другой перспективе. Есть ли способ, как заставить его работать с любым реальным числом, например. 1,8?

+0

Прочитайте все в строку и проанализируйте ввод соответственно? – Rhexis

+0

Используйте cin.get(), а затем проверьте символ EOF? – Ansari

ответ

7

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

#include <string> 
#include <sstream> 

int main() 
{ 
    std::string line; 
    double d; 
    while (std::getline(std::cin, line)) 
    { 
     std::stringstream ss(line); 
     if (ss >> d) 
     { 
      if (ss.eof()) 
      { // Success 
       break; 
      } 
     } 
     std::cout << "Error!" << std::endl; 
    } 
    std::cout << "Finally: " << d << std::endl; 
} 
19

Когда cin встречает вход, он не может правильно прочитать указанную переменную (например, ввод символа в целочисленную переменную), он переходит в состояние ошибки и оставляет вход в его буфер.

Чтобы справиться с этим сценарием, вам нужно сделать несколько вещей.

  1. Вы должны проверить это состояние ошибки.
  2. Вам необходимо очистить состояние ошибки.
  3. Вы должны либо альтернативно обрабатывать входные данные, которые генерировали состояние ошибки, либо вымывать их и перепроектировать пользователя.

В следующем коде представлен один из многочисленных способов выполнения этих трех действий.

#include<iostream> 
#include<limits> 
using namespace std; 
int main() 
{ 

    cout << "Enter an int: "; 
    int x = 0; 
    while(!(cin >> x)){ 
     cin.clear(); 
     cin.ignore(numeric_limits<streamsize>::max(), '\n'); 
     cout << "Invalid input. Try again: "; 
    } 
    cout << "You enterd: " << x << endl;   
} 

Вы можете просто передать в каком-то большом значении для cin.ignore как 1000, и это, вероятно, ведут себя точно так же для всех практических целей.

Вы можете также проверить cin после попытки ввода и обработать его таким образом, что-то вроде if (! Cin) {// очистить ошибку}.

Заканчивать ссылка IStream для других функций-членов для обработки потока состояния: http://cplusplus.com/reference/iostream/istream/

+0

Эта линия 'cin.ignore' очищает его, верно? – Jeff

+0

@Jeff Да, он смывает буфер. Вы также можете использовать его при использовании cin с getline при вводе данных, поскольку cin оставляет «\ n» в буфере и не удаляет (я считаю, не совсем уверен, может быть, это cin.get), поэтому getline просто ограничивает момент, который он прикрепляет к входному буферу, когда он встречает слева над '\ n'. –

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