-2

In my code, a certain cin asks for two inputs(values or enter and values) instead of one, despite using cin.clear and cin.ignore. Anyone have an idea what the problem is?

PS Yes, there are 16 other functions and main() where you can choose which one you want to run. None of them have such a issue.

int fun;
char choice;
do {
    cout << "text" << endl;
    cin.clear();
    cin.ignore( 255, '\n');
    cin >> fun; //              <<<  THIS ONE 
    switch (fun) {
        case 1:
            twoNums();
            break;
        default:
            cout << "wrong" << endl;
            return 0;
    }
    cout << "text" << endl;
    cin >> choice;
}
while(choice != 'n');
cout << "Quit." << endl;
return 0;
  • 1
    What do you mean? You ask for two inputs, one at the beginning of the loop and one at the end of the loop. – Yksisarvinen Nov 25 '19 at 19:03
  • @Yksisarvinen Sorry, my bad. Just edited and added "THIS ONE" pointer. –  Nov 25 '19 at 19:06
  • Why do you think that one needs two inputs, if there is another one following (or coming immediatly before, depending on how you read your loop)? – Yunnosch Nov 25 '19 at 19:06
  • Please make a [mre]. – Yunnosch Nov 25 '19 at 19:07
  • 2
    It is not an issue that inputting a character that way will require a following return, is it? – Yunnosch Nov 25 '19 at 19:08
  • You improved the "minimal". Now strive for the reproducable. For that the shown code should compile. Please read the MRE link completely. – Yunnosch Nov 25 '19 at 19:09
  • Possible duplicate of [Capture characters from standard input without waiting for enter to be pressed](https://stackoverflow.com/questions/421860/capture-characters-from-standard-input-without-waiting-for-enter-to-be-pressed) – Mitch Lindgren Nov 25 '19 at 19:19

2 Answers2

2

Short answer:

You are misusing cin.ignore() and cin.clear(). Remove those two lines.

Long answer:

Let's go step by step through your code.

cin.clear();

First, you ask to clear flags on cin. There were not flags set, so it doesn't do anything.

cin.ignore( 255, '\n');

You ask to skip next 255 characters or up until '\n' is reached. The stream is empty, so none of these conditions is met until the end of input data. From documentation on std::basic_istream::ignore(), eof flag is set on stream and input characters are left in stream.

cin >> fun;

You try to extract data from stream, but eof flag is set. Extraction fails silently, fun becomes 0 if you are using C++11 standard or newer, or is left unitialized if you are using old compiler. I'm assuming modern compiler later on.

switch (fun) { }

case 0: or default: will be executed.

cin >> choice;

Again, eof bit set, extraction failed. choice is zeroed.

} while(choice != 'n');

'\0' != 'n', continue the loop.


Now comes the fun part, why it starts working at second loop iteration?
Lets go through the loop again:

cin.clear();

You clear the eof flag set in previous iteration, stream is non-empty and in good() state.

cin.ignore( 255, '\n');

You ignore the values inputted in the previous iteration. Depending on how you input values, but it will skip until first \n.

cin >> fun;

If the next value in the stream is integer, you have successful extraction! From now on, if values inputted are valid for the data type, the loop will work correctly.

Community
  • 1
  • 1
Yksisarvinen
  • 18,008
  • 2
  • 24
  • 52
2

your use of cin.ignore is incorrect. move it to the spot where it is really required. In this case the new line has to be ignored just after the last integer has been read so that you can read in the choice.

Something like:

    cout << "text" << endl;        
    cin >> fun; //              <<<  THIS ONE 
    switch (fun) {
        case 1:
            twoNums();
            break;
        default:
            cout << "wrong" << endl;
            return 0;
    }

    cout << "text" << endl;
    cin.ignore( 255, '\n');  //move it here   
    cin >> choice;

Also take a look at this SO thread When and why do I need to use cin.ignore() in C++?

pcodex
  • 1,812
  • 15
  • 16