-3

I have a question about c++. I've been searching for an answer and have found nothing that will fix my code. So I decided to ask myself. My problem is, that I made this little program that will output the day of the week, so if the user inputs 1, it will output the 1st day of the week (Sunday or Monday, depends on where you live) and so on and so forth. However, if the user inputs for example, 8, then the program will output "Please choose a number between 1 and 7!" However, my problem is that when the user inputs a character or random word, it will loop "Please choose a number between 1 and 7!" forever.

    #include <iostream>
#include <Windows.h>
#include <string>
using namespace std;


int main() {

    int input;


    do {
        cin >> input;
        switch (input) {
        case 1:
            cout << "Sunday" << endl;
            break;
        case 2:
            cout << "Monday" << endl;
            break;
        case 3:
            cout << "Tuesday" << endl;
            break;
        case 4:
            cout << "Wednesday" << endl;
            break;
        case 5:
            cout << "Thursday" << endl;
            break;
        case 6:
            cout << "Friday" << endl;
            break;
        case 7:
            cout << "Saturday" << endl;
            break;
        default:
            cout << "Please choose a number between 1 and 7!" << endl; // if user chooses a number not from 1-7 output this. But if input is not an int and for example "a", it will loop this forever.
            break;
        }

    } while (true);


    return 0;
}
DanTheMan
  • 61
  • 2
  • 7

2 Answers2

0

IO operations sets flags about current state of stream.

These are important flags, what you should care about if reading input

  • badbit - Read/writing error on i/o operation
  • failbit - Logical error on i/o operation
  • eofbit - End-of-File reached on input operation

If you pass an character to stream which expects int (pass an wrong datatype overall, which cannot be converted to type that cin expects), the failbit is set.

Thats the reason why you got into infinite loop after inserting wrong input. failbit was set and cin wasn't cleared, so next reading operation failed as well and again and again.

The thing to do is unset failbit and discard the bad input from the input buffer using ignore.

std::cin.clear();      // without params clears flags
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // Clear input buffer

std::cin.fail() will tell you if failbit is set (wrong IO operation).

int input;
cin >> input;
while (! cin.fail())
{
   // Process data
   cin >> input;
}

and std::cin.eof() will tell you if eofbit is set, reach EOF (CTRL+D/+Z on std input)

if (cin.eof())
{
    // End of file (input) reached
    // Terminate reading
}
kocica
  • 6,412
  • 2
  • 14
  • 35
0

Statement cin >> input may fail, e.g. if a user inputs something that cannot be converted to an integral value, or if the stream reaches EOF (e.g. CTRL-D or CTRL-Z in standard input). If cin >> input fails, two things happen: First, an error state is set, indicating the type of failure. Second, the expression returns false, indicating that no value has been written to input.

So you should always check the result of cin >> ... before going ahead. And, if you detect an invalid input, you will have to reset the error flag (using cin.clear()) before reading in again, and you might want to skip the invalid input (using cin.ignore(...)) in order to avoid reading in the same (invalid) input again and again:

int main() {

    int input;
    while (true) {

        while (!(cin >> input)) {

            if (cin.eof()) {
                cout << "user terminated input." << endl;
                return 0;
            }
            cout << "invalid input (not a number); try again." << endl;
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(),'\n');
        }

        // from here on, you may rely that the user has input a number.

        cout << input;

        // ... your code goes here
    }

    return 0 ;
}

Note that you should specifically allow the program to exit when reaching EOF. Otherwise, you may run into an infinite loop when you pass a file with invalid content as input to your program (e.g. by myProgram < input.txt).

Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58