How to clear buffer in numeric menu when typing strings?

Asked

Viewed 268 times

1

How to implement a menu that reads numeric values and indicates error (message on screen) when receiving characters and strings? The code below worked well for individual characters through the if(std::cin >> opcao), but for strings it stores the buffer and overwrites several times - depending on the string size.

Code:

#include <iostream>
#include "Elemento.h"

int main()
{
    int opcao;

    Elemento e = 0;

    Elemento::mostrarMenu();

    do{
        std::cout << "Opção: ";

        if(std::cin >> opcao){          

            switch(opcao){

                case 1:
                    Elemento::adicionar(e);
                    Elemento::listar();
                    break;

                case 2:
                    Elemento::listar();
                    break;

                case 3:
                    std::cout << "Encerrando." << std::endl;
                    break;

                default:
                    std::cout << "Opção inválida." << std::endl;
                    break;      
            }// fim switch()

            std::cin.clear();
        }//fim if cin
        else{

            std::cin.clear();
            std::cin.ignore();
            std::cout << "Digite um número válido" <<std::endl;
        }

      std::cin.clear();
      std::cin.ignore();
    }
    while(opcao != 3); // fim do - while()
}

Build command:

clang++ -Wall -ansi -O main.cpp Elemento.cpp -o Elemento

Execution:

Menu: 1 - Adicionar. 2 - Mostrar. 3 - Sair. Opção: r Digite um número válido Opção: rafael Digite um número válido Opção: Digite um número válido Opção: Digite um número válido Opção: _

How to display the notice in else only once, even if the user type a string?

I put several cin.ignore and cin.clear that improved the situation but did not. What is the simplest (and/or efficient) way to deal with this situation?

1 answer

1


Your case is quite simple. You only need to read the rest of the string. You can use the following code on Else.

else
    {
        //bad token
        cin.clear();
        string badToken;
        cin >> badToken;
        cerr << "Entrada invalidade encontrada: " << badToken << endl;
    }

So when the loop starts again the buffer will be empty. You can also read all characters with a Cin.get() in a while, but I find it easier to read everything in a string all at once. And also Cin.clear() doesn’t clear the buffer it just resets Cin’s state to default. Then you can remove Cin.clear() and Cin.ignore() after Else.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.