Infinite loop when typing a character

1

I'm doing error testing on my "Monkey Test" program and it goes into loop infinity when I type a character on the keyboard other than number.

int ActionGenerator() {

    bool Verify;
    int Action;
    Verify = true;

    while(Verify){
        cout << "\nSELECIONE UMA ACTION: " << endl;
        cout << "[1 = ActionX]\n[2 = ActionZ]" << endl;
        cin >> Action;

        if (Action == 1 || Action == 2){
            return Action;
            Verify = false;

        }else {
            cout << "\nACTION INVALIDA !" << endl;
        }
    }
}
    
asked by anonymous 25.11.2014 / 22:20

3 answers

0
int ActionGenerator() {

    int opcao;
    char *CleanBuffer;


    do{
        cout << "\nSELECIONE UMA ACTION: " << endl;
        cout << "[1 = ActionX]\n[2 = ActionZ]" << endl;
        scanf("%d", &opcao);
        scanf("%c", &CleanBuffer);

        if (opcao = 1) {
            return opcao;


        }else if(opcao = 2){

            return opcao;

        }

        else {
            cout << "\nACTION INVALIDA !" << endl;
        }

    }while(opcao != 3)


    return 0;
}
    
05.12.2014 / 18:37
4

I did another test and the original code I posted does not work in any situation. I did another one that is more complicated, but it works. It takes a string and tries to convert it to int . If it fails, it is the same as if the number is invalid. Before it works when there was a specific error, it now handles any invalid input. And as it is done through specialized function, you do not have to worry about the state of the stream pattern.

#include <iostream>
#include <string>
#include <sstream>

using namespace std;

int ActionGenerator() {
    int Action;
    string Input = "";
    while(true) {
        cout << endl << "SELECIONE UMA ACTION: " << endl;
        cout << "[1 = ActionX]" << endl << "[2 = ActionZ]" << endl;
        getline(cin, Input);
        stringstream myStream(Input);
         if ((myStream >> Action) && (Action == 1 || Action == 2)){
            return Action;
        } else {
            cout << endl << "ACTION INVALIDA !" << endl;
        }
    }
}

int main() {
    cout << ActionGenerator() << endl << "ok" <<endl;
    return 0;
}

See running on ideone . And no Coding Ground . Also I placed GitHub for future reference .

Note that I ran a test with a string more than one character. This failed in the previous code.

The code is difficult to understand because it is not badly indented. It may seem silly but this makes a huge difference to understanding the code.

There is a part that will never be executed. And in fact there is no logic to get out of loop unless you enter 1 or 2. And in these cases the function execution terminates.

But the problem is that you are not releasing the stream state. When an error occurs an error flag is set to let you know there was a problem when you tried to get a valid value. When you type something that can not be converted to the expected type, in the case a int , in addition to the number being converted to 0, is flag set set and only if you explicitly clear this is that you can go back to working with stream . If the flag is set, the stream does not work.

Another problem is that the typed data is still in buffer and you need to ignore what is in it.

That is, the stream saves state and you have to solve this.

I took advantage of and made an improvement for this case:

#include <iostream>
using namespace std;

int ActionGenerator() {
    int Action;
    while(true) {
        cout << endl << "SELECIONE UMA ACTION: " << endl;
        cout << "[1 = ActionX]" << endl << "[2 = ActionZ]" << endl;
        cin >> Action;
        if (Action == 1 || Action == 2){
            return Action;
        } else {
            cout << endl << "ACTION INVALIDA !" << endl;
            cin.clear(); //Limpa a flag de erro quando há falha no parse do valor entrado
            cin.ignore(); //Limpa o buffer
        }
    }
}

int main() {
    cout << ActionGenerator() << endl << "ok" <<endl;
    return 0;
}

See running on ideone . Also I placed GitHub for future reference .

There are other ways to handle this but I think for the simple example you gave you do not have to do anything more complex than this.

Note that I simplified the loop as well. There was no reason to exist that control in this case.

    
25.11.2014 / 23:05
-1

The cin>> command does not handle invalid entries. Action is an integer, if someone enters a string, it generates an unhandled exception, which ends up generating the infinite loop. You have to generate a code to handle this exception. You have to catch an entry of type array ( char[] ), convert it to numbers, with exception handling for invalid entries, type:

if ( char[0] != '1' )
    ThrowException(); //Seu método para tratar e exceção
else
    number += 1 * (decimalPlace ); // primeira casa decimal neste caso.

Note: verify = false after return Action will never be executed.

    
25.11.2014 / 23:04