C ++ cin.fail () question

When you run the following code and enter a number, it works fine. But when entering a letter, the program enters an endless loop, displaying "Enter a number (0 to exit): cin failed."

My intention was to handle the cin failure case and request the user again.

int number;
do{
    cout << "Enter a number (0 to exit): ";
    cin >> number;
    if(cin.fail()){
        cout << "cin failed." << endl;
        cin.clear();
    }else{
        cout << "cin succeeded, " << number << " entered." << endl;
    }
}while(number != 0);
+3
source share
3 answers

You need to clear the string from cin using cin.ignore, in addition to clearing the state of the stream (which cin.clear does).

, ( , , clearline, ) .

, , :

#include "clinput.hpp" // move my file to a location it can be used from

int main() {
  using namespace std;
  while (true) {
    cout << "Enter a number (0 to exit): ";
    int number;
    if (cin >> number) {
      cout << "Read " << number << '\n';
      if (number == 0) {
        break;
      }
    }
    else {
      if (cin.eof()) { // tested only *after* failed state
        cerr << "Input failed due to EOF, exiting.\n";
        return 1;
      }
      cerr << "Input failed, try again.\n";
      clearline(cin); // "cin >> clearline" is identical
    }
  }
  return 0;
}

- ( ​​ clinput_loop.cpp ), , (. "42 abc" ). , :

template<class Type, class Ch, class ChTr>
Type read(std::basic_istream<Ch,ChTr>& stream, Ch const* prompt) {
  Type value;
  // *try input here*
  if (could_not_get_input or more_of_line_left) {
    throw std::runtime_error("...");
  }
  return value;
}
template<class Type, class Ch, class ChTr>
void read_into(
  Type& value,
  std::basic_istream<Ch,ChTr>& stream,
  Ch const* prompt
) {
  value = read<Type>(stream, prompt);
}

:

int n;
try {
  read_into(n, std::cin, "Enter a number: ");
}
catch (std::runtime_error& e) {
  //...
  raise;
}
cout << "Read " << n << '\n';

clearline, , , - ( , ):

#include <istream>
#include <limits>

template<class C, class T>
std::basic_istream<C,T>& clearline(std::basic_istream<C,T>& s) {
  s.clear();
  s.ignore(std::numeric_limits<std::streamsize>::max(), s.widen('\n'))
  return s;
}

, , :

  • std:: istream - typedef std::basic_istream<char, std::char_traits<char> >
  • std:: wistream - typedef std::basic_istream<wchar_t, std::char_traits<wchar_t> >
  • widen '\n' L'\n'
  • char, wchar_t, basic_istream
  • clearline(stream) stream >> clearline, , std:: endl, std:: ws std:: boolalpha
+5

, , :

#include <iostream>
using namespace std;

int main ()
{
  int i;
  do {
    if (cin.fail())
    {
      cin.ignore(255);
      cin.clear();
    }          
    cout << "Please enter an integer value: ";
    cin >> i;
  } while ( cin.fail() );
  cout << "The value you entered is " << i;
  return 0;
}
+1

cin.fail() ,

#include <iostream>
using namespace std;

int main()
{
int j;
int i;

i = 0;
while (1) {
    i++;
    cin >> j;
    if (cin.fail()) return 0;
    cout << "Integer " << i << ": " << j << endl;
}
}

Input:

42 51 85 85

:

Integer 1: 42

Integer 2: 51

Integer 3: 85

0
source

Source: https://habr.com/ru/post/1727845/


All Articles