-1

My code is meant to allow a user to input a number 0-9 and out that number as a string. i.e. 1 = "one". Pressing Ctrl + D exits the code. Here it is for reference:

#include <iostream>
using namespace std;
#include <stdio.h>

int main(){
    int num;
    while ( !cin.eof() ) {
        cin >> num;
        switch(num) {
            case 0 :
                cout << "zero" << endl; 
                break;
            case 1 :
                cout << "one" << endl; 
                break;
            case 2 :
                cout << "two" << endl; 
                break;
            case 3 :
                cout << "three" << endl; 
                break;
            case 4 :
                cout << "four" << endl; 
                break;
            case 5 :
                cout << "five" << endl; 
                break;
            case 6 :
                cout << "six" << endl; 
                break;
            case 7 :
                cout << "seven" << endl; 
                break;
            case 8 :
                cout << "eight" << endl; 
                break;
            case 9 :
                cout << "nine" << endl; 
                break;
        }
    }
    return 0;
}

When I input the correct integers, the code behaves as it should. If input a double digit integer like 10, the code just ignores it, which is fine. However if I put in a non-int like "i", "f" or "cat" the program spams "zero" repeatedly and Ctrl + D no longer works to end the program.

Why is this happening? Is there a way to set it so inputting non-ints would behave the same way as inputting double digit ints? If not, is there a way to only allow cin to take in integers? Thanks!

Zevvysan
  • 283
  • 1
  • 10
  • 4
    [why `while (!cin.eof())` is wrong](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong) – Barmar Feb 03 '18 at 07:41
  • Other than checking for `eof()` - which is bad enough - the only direct interaction you have with `cin` in your loop is `cin >> num` which, if the user enters anything that cannot be interpreted as an integral value, sets the stream to a fail state AND leaves the unexpected input in the stream - so it will be read again. Why would you expect anything other than the behaviour you're seeing? Anyway, try reading characters directly from the stream into a string (which will accept any valid characters the user types) and then parse the strings. – Peter Feb 03 '18 at 11:12

1 Answers1

0

At an invalid input, cin >> num is stuck. You need to reset the stream to "good state" and clear the bad input.

It's also recommended that you check for EOF immediately after attempt to input.

while ( true ) {
    cin >> num;
    if ( cin.eof() ) break;
    if ( !cin ) {
        cerr << "Bad input" << endl;
        cin.clear();
        cin.ignore();
    }
    switch(num) {
        case /* your code ... */
    }
}
iBug
  • 30,581
  • 7
  • 64
  • 105
  • After the input? How does that work? If I do that, how does the program allow the user a chance to break it? Right now it allows input/break and then gives an output before giving the user another chance to input break. But if I had it check after the input, wouldn't the window of time between output and more requested input be too small to break from? – Zevvysan Feb 03 '18 at 17:27
  • @Zevvysan The functionality remains unchanged. If the user enters `aasdadadafafa`, it complains about bad input. If the user gives EOF, then it quits. Maybe you didn't understand the code? – iBug Feb 04 '18 at 03:51