Doubt of C++ loop do-while

Asked

Viewed 481 times

3

Good people, I have the following question:

Every time I run that program the do-while loop doesn’t stop at the second loop scanf in the program and ends up running twice and displaying the error message. I would like to know how to fix this bug.

#include <stdio.h>
#include <stdlib.h>

int main(void){

int a1, a2, media;
char op;

do{

    printf("Digite a primeira nota: ");
    scanf("%i", &a1);

    printf("\nDigite a segunda nota: ");
    scanf("%i", &a2);

    printf("\n\nMEDIA: %d", ((a1+a2)/2));

    do{
        printf("\n\nDigite 's' para rodar o programa denovo ou 'n' para encerrar: ");
        scanf("%c", &op);

        if ((op!='s') && (op!='n')){
            printf("Opcao invalida");
        }

    }while((op!='s') && (op!='n'));     
}while(op!='n');

return 0;
}
  • What do you mean 'not stop' ? you can show how it comes out on the console?

  • i answered below - but there’s a tip off topic: if you want to learn programming logic, without having to worry about low-level file stream logic, memory allocation, and still have programs that can do real tasks, try a higher level language like Python or Ruby. In C/C++, a simple reading of user input can, in addition to the problems you’ve had, add dangerous security holes - see my answer.

2 answers

1

The reading of the standard input can be a bit boring sometimes - the scanf and printf functions were written more than 30 years ago, when the capacity of the terminals (and interface to the programs in general) were well heated than they are today.

The default entry works as a text file - which for the sake of typing, unless you change some very complicated settings, is always read line by line - so even using %c in the scanf, or the function getchar as suggested in the other reply, the user will have to press <enter> - and that <enter> will be read - or next scanf, or the next getchar.

The best is not to try to read character by character - the user will have to press enter even. If you want to create an interface that responds to keyboard shortcuts, then it is best to use a console library, such as ncurses - it makes adjustments to the stdin configuration so that you can read key to key without side effects. But this is a stage beyond familiarization with the language that is the point of your current program - and possibly, it’s worth learning to use a graphical library for interface rather than ncurses (gtk, Qt, etc...)

Finally, for your current program, use the scanf with "%s" - but - remember, at all times that using scanf to read a string, it is necessary to think about what would happen if the user typed more data than fits into his string to store the data. Simple: too much data leaks into other memory regions in use by your program and this causes the famous "buffer overflow". To mitigate this, the "%s" must be used with the maximum number of characters that the user must type, between "%" and the "s" - scanf("%21s") - accepts a string of up to 20 characters (plus the final x00).

Your program can be done like this:

char op[3]; //suficiente para conter a letra da opção, o \n e o \x00
...
scanf("%2s", op) // op já é um ponteiro - não precisa do &
...
while (op[0] != 's') && (op[0] != 'n') // verifica apenas o 1º caractere da string op

1


I advise you to use the getchar(). To work with the scanf you should clean the buffer with flush(stdin) because the enter \n stays in the stdin.

  • I’m not familiar with these functions yet, I’m not very familiar with the c/c++ syntax, but thanks for the help

  • before your sacanf just put 'flush(stdin);'. When you type the value of the variable i and enter your next scanf which in this case is the first of the second do-while reads the enter that is in the buffer, why you should clean with flush(stdin);

  • It is common the flush() does not work, so the solution should be the getchar().

  • But getchar does not remove stdin ' n' either - the program will even work, but without a flush, it will display the 'invalid option' message because of ' n'

Browser other questions tagged

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