Scanf is not stopping on repeat

Asked

Viewed 1,222 times

4

I have a loop while which will only end when 0 (zero) is entered. I have a variable which will receive a command option. Inside the loop I own a switch marry where:

  • 0) exits the program (returns to while and ends);
  • 1) requests that a letter be written;
  • 2) shows the letter written.

Well, the problem is actually case 1. Follow the code made:

file: teste_while_e_switch. c

#include <stdio.h>

int main()
{
  int op=-1;
  char letra=' ';

  while(op!=0){
      printf("\n0) sair\
      \n1) digite uma letra\
      \n2) mostre a letra\
      \nOp: ");
      scanf("%d", &op);

      switch(op){
          case 0: { break; }
          case 1: { printf("letra: "); scanf("%c", &letra); break; }
          default:{ printf("opcao invalida.\n"); break; }
      }
  }
  printf("fim");
  return 0;
}

When running the program it behaves as follows:

0) sair
1) digite uma letra
2) mostre a letra
Op: 1
letra:
0) sair
1) digite uma letra
2) mostre a letra
Op:

As far as my understanding extends, loop should show the message of op, wait until I typed a letter and only then follow the code showing again the menu.

  • 2

    This is the old problem of scanf. You can’t use it with impunity buffer.

  • @Bigown would explain me better about this? And if possible a way to resolve this. Actually I can type the letter and it returns when I access option 2, however the loop goes on without waiting for me to type, so it seems that I am typing a new option and not the letter I would like.

  • 1

    I removed my comments because I hadn’t seen the problem at first. That’s exactly what @bigown said, problem with scanf. He’ll probably post an answer.

  • Related: http://answall.com/q/42981/101

  • First I would like to thank lvcs and bigown because they were the ones who were able to help me and understand the problem. For those with a problem similar to mine: Just adding a space before the formatting of the scanf was possible to solve, all the explanations in detail are in the comments and answers, plus other tips that may be useful for other cases.

1 answer

6


I decided to respond to give a code cleaner and within the standards:

#include <stdio.h>

int main() {
    char op = ' ';
    char letra = ' ';
    do {
        printf("\n0) Sair\
            \n1) Digite uma letra\
            \n2) Mostre a letra\
            \nOp: ");
        scanf(" %c", &op);
        switch (op) {
            case '0':
                break;
            case '1':
                printf("\nLetra: ");
                scanf(" %c", &letra);
                break;
            case '2':
                printf("\nLetra digitada: %c", letra);
                break;
            default:
                printf("\nOpcao invalida.");
        }
    } while (op != '0');
    printf("fim");
}

Behold working in the ideone. And in the repl it.. Also put on the Github for future reference.

There’s still some bad logic in it, but for an exercise it’s good.

The use of fgets() is even more recommended than scanf() that can be used in simple things like this.

If you want to get rid of ENTER can do so:

#include <stdio.h>

int main() {
    char op = ' ';
    char letra = ' ';
    do {
        printf("\n0) Sair\
            \n1) Digite uma letra\
            \n2) Mostre a letra\
            \nOp: ");
        op = getchar();
        switch (op) {
            case '0':
                break;
            case '1':
                printf("\nLetra: ");
                letra = getchar();
                break;
            case '2':
                printf("\nLetra digitada: %c", letra);
                break;
            default:
                printf("\nOpcao invalida.");
        }
    } while (op != '0');
    printf("fim");
}

Behold working in the ideone. And in the repl it.. Also put on the Github for future reference.

  • Got it, adding the space in the scanf the problem had already been solved, I did not know this problem with buffer. Actually I developed this exercise just to try to understand what was going on in another code that I was doing related to lists, because it was going into the same loop problem and didn’t allow me to type the option correctly.

  • Both the scanf with %c like the getchar will have problems with the newline character, will not? (It stays in the buffer and is read in the next input operation) . In that case perhaps it is better to fgets or scanf with %s. (And for users wanting to avoid enter, time to move on to new Remakes: ncurses, or graphic biblitoecas, or this combined with high-level and high-level programming languages )

  • The intention is to have only one character. In fact for real things, none of this is a solution, but for exercise, okay.

  • @mustache the two links to the ideone is for example using scanf(" %c", &op);

  • @Pablotondolodevargas ah, blz, I’ll see what I can do to fix.

Browser other questions tagged

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