Switch locks command when entering a letter

Asked

Viewed 142 times

0

I’m making a code that uses switch (because the user can’t give any input) where I need the user to determine if r0 will have the integer value of 1 or 2, any other number will cause the question to be redone. My problem is when a letter is placed, which causes the code to be in a locked loop, some suggestion to fix it?

pergunta1() {
cin >> r0;
switch (r0){
    case 1:
        pergunta2();
    case 2:
        pergunta2();
    default:
        pergunta1();
}
  • You probably defined the R0 variable as an integer. Set the R0 variable to a character (char) and make sure that what was typed is a valid character for your program, so I understand from your problem either '1' or '2', all others are invalid characters.

3 answers

1

Use a stringstream to receive cin as the stream processes the characters one by one and interrupts the process if there is an invalid character according to the type requested.

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

using namespace std;

void pergunta2(void ){
  std::cout << "pergunta2" << std::endl;   
}

void pergunta1(void ) {

      std::cout << "pergunta1" << std::endl; 

      string input;
      getline(cin, input);
      stringstream buffer(input);

      //std::stringstream buffer;
      // Descomente a próxima linha caso r0 ainda não tenha sido declarado
       int r0; 

      //buffer << std::cin;
      buffer >> r0; 

      switch (r0){
          case 1:  // fall through      
          case 2:
              pergunta2();
              break;
          default:
              pergunta1();
       }
   }

int main()
{

    pergunta1();

    return 0;
}
  • nor does it compile...

  • I modified the code to make it easier for those who have difficulty with streams.

  • there is no advantage in exchanging Cin (istream) for buffer (stringstream) in this second version...when you do "Cin >> R0" and "buffer >> R0" the effect is the same

  • 1

    @zentrunix cin >> r0 and buffer >> r0 have very different effects. Read the first two lines.

  • the difference in behavior in its version is caused by getline (not "buffer >> R0"), which consumes the wrong line when a letter is typed instead of a number, but in this case the asked function is called recursively, and others Copies of input and buffer are created...I’m sorry, but this is not an acceptable solution...what should be done to solve the root problem is to consist of the result of "Cin >> R0" (or "buffer >> R0" in its version)...additionally the recursive query call must be deleted to avoid memory Leak

0

Note the variable declaration r0. Analyzing the switch, it is possible to infer that you have declared the variable r0 with the guy int. This is causing the loop. Try to adapt your code to the following:

void pergunta1() {
    char r0;

    cin >> r0;

    switch (r0){
        case '1':
            pergunta2();
            break;
        case '2':
            pergunta2();    
            break;
        default:
            printf("Valor inválido!\n");
            pergunta1();
    }
}

Note the variable declaration r0, with the guy char. And also in the structure of switch which now has simple quotes to validate the values.

  • 1

    switch does not cause loop...and in the example in question the change you suggested is innocuous

  • Can you show where it was said that the "switch" is causing the loop? And unlike what you claim, run the two codes and make sure the change I suggested does not fix the reported problem. Before negative, test the code..

  • you are right, actually switching to the type of R0 to char corrects the loop, but consider this a patch, because the root cause of the problem is a conjunction of 2 factors: the non-verification of the "Cin >> R0" result, and the use of recursiveness...in this situation, When something is typed that is not number the program goes into infinite loop...Keyboard reading is a notoriously difficult task for beginners in both C and C++...I edited my answer to put a robust solution to the question

  • (edit your answer so I can take the negative vote)

-2

UPDATE

Placing here a robust version of the program that has been posted.

The root cause of the problem (infinite loop) is a conjunction of 2 factors: the unverification of the "Cin >> R0" result, and the use of recursion.

In this situation, when something non-numerical is typed, the program enters an infinite loop.

Keyboard reading is a notoriously difficult task for beginners in both C and C++.

#include <iostream>
#include <string>
using namespace std;

static void pergunta2()
{
  cout << "* pergunta2\n";
}

static void pergunta1()
{
  int r0;
  string resto_da_linha;

  // loop de execucao de pergunta1
  for (;;) // #1
  {

    // leitura e consistencia da digitacao
    for (;;) // #2
    {
      cout << "* digite uma opcao: 1 ou 2: " << flush;
      if (cin >> r0)
      {
        // sucesso na leitura de um numero
        break;
      }
      cout << "* erro, digitacao invalida (digitar apenas numeros)\n";
      cin.clear(); // como houve erro na leitura, precisa limpar o estado de cin

      // cin.ignore(1000, '\n');    // opcao 1 para limpar o buffer de entrada
      getline(cin, resto_da_linha); // opcao 2 para limpar o buffer de entrada
    } // for #2

    // por via das duvidas limpa o buffer de leitura,
    // caso o usuario tenha digitado coisas demais
    // cin.ignore(1000, '\n');
    getline(cin, resto_da_linha);

    switch (r0)
    {
      case 1:
        pergunta2();
        break;
      case 2:
        pergunta2();
        break;
      default:
        cout << "\n* erro, opcao invalida\n\n";
        break;
    } // switch
  } // for #1
} // pergunta1

int main()
{
  pergunta1();
}
  • 2

    In case it is "wrong" only for the intended use, after all it is perfectly normal (and often necessary) to use the switch without the break in one or more conditions if the cascade effect is desired. I commented only to demystify the need for break as a universal rule, in case a beginner comes to read the post. - As for the recursive use of the function, it really is very suspicious. It seems a bad idea, but without seeing the author’s requirements, it is difficult to know.

  • @Bacco is debatable whether it is "perfectly normal" to use a break-free switch, so much so that it is recommended to document that it is on purpose that the break was not used

  • 1

    I don’t think there’s much to discuss - If it wasn’t normal case The break is separated from the next case so that it is used only when necessary. The break is separated from the next case. The problem is that people don’t understand that the switch (and the break) function in a manner analogous to goto and not to a structure if elseif else (this deception I see in a lot of material internet around). Two things that are powerful and poorly taught in programming are switch and state machines.

  • 1

    Use case without break is known as Fall through and as far as I know its use is natural since the 80s, when I started programming in C.

  • @Augusto Vasques "natural" based on what parameter ? if it’s the amount of times you use a case without break vs break, then I don’t consider it "natural"

  • @Bacco fallthrough is not the case for "normal" use, so much so that in C++17 an attribute was created for this case https://en.cppreference.com/w/cpp/language/attributes/fallthrough

  • For the structure of the question1 function presented, it is clear that recursive use does not interfere with the process. This would not be the code structure that I would use, but it is not up to discuss here the best method to build this function.

  • @E. Thomas: in fact, the use of recursion in this case is one of the factors that causes the infinite loop in the program that was posted

Show 3 more comments

Browser other questions tagged

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