C ++ doubts do-while loop

3

Good people, I have the following doubt:

Every time I run this program the do-while loop does not stop at the second loop scanf in the program and ends up running twice and displaying the error message. I'd 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;
}
    
asked by anonymous 15.01.2016 / 13:12

2 answers

1

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

    
15.01.2016 / 13:23
1

Reading the standard input can be a bit annoying at times - the scanf and printf functions were written more than 30 years ago, when the capacity of the terminals (and interface for the programs in general) were well today.

The standard input acts like a text file - which for reasons of optimization, unless you change some very complicated settings, it is always read row by line - so even using %c in scanf or the getchar function as suggested in the other response, the user will have to press <enter> - and this <enter> will be read - or next scanf , or next getchar .

It is best 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 better to use a console library, such as ncurses - it makes adjustments to the stdin configuration so that you can read the key without any side effects. But this is a stage beyond familiarizing with the language that is the point of your current program - and possibly, it's worth learning to use a graphical interface library rather than ncurses (gtk, qt, etc ...) / p>

Finally, for your current program, use scanf with "% s" - but - remember, always you use scanf to read a string, you need to think about what would happen if the user entered more data than would fit in his string to store the data. Simple: the data leaks to other regions of memory in use by your program and this causes the famous "buffer overflow". To mitigate this, "% s" should be used with the maximum number of characters the user must enter, between "%" and "s" - scanf("%21s") - accepts a string of up to 20 characters x00 final).

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
    
16.01.2016 / 15:59