Program does not read scanf

Asked

Viewed 4,136 times

4

I am doing a school job, doing a blackjack (21) on C. In a certain part of the program, I created a while (while the option is yes) to show the cards, the score and ask if the user wants to bet again (yes or no) at the end of the while. Only that the compiler terminates the program and does not read the scanf at the end of while. If anyone can tell me how to fix it, I’d be grateful, I have to deliver it today.

#include <stdio.h>
#include <stdlib.h>
#define max 21

int main() {
    char naipe, nome[50], op;
    char tipo[13] = {'A','2','3','4','5','6','7','8','9','10','J','Q','K'};
    int valor, valorb, soma=0, somab=0;
    int i,din=1000;
    int aposta, taposta=0;

    printf("Digite o seu nome:\n");
    scanf("%s",&nome);
    op='S';

    do {
    system("cls");
    printf("Você tem %d unidades\n",din);
    printf("Escolha sua aposta inicial, %s:\n",nome);
    printf("Digite 1 para 10 unidades\n");
    printf("Digite 2 para 20 unidades\n");
    printf("Digite 3 para 50 unidades\n");
    scanf("%d",&aposta);
    } while (aposta<1 || aposta>3);
    switch (aposta) {
    case 1:
        taposta+=10;
        break;
    case 2:
        taposta+=20;
        break;
    case 3:
        taposta+=50;
        break;
    }


    while ((op=='s') || (op=='S')) {

        srand(time(NULL));
        i=rand()%12+1;
        if ((i==11) || (i==12) || (i==13))
            valor=10;
        else if (i==1)
            valor=1;
        else
            valor=i;
        naipe=rand()%3+3;
        soma=(soma+valor);

        printf("_________\n");
        printf("|%c      |\n",naipe);
        printf("|       |\n");
        printf("|   %c   |\n",tipo[i]);
        printf("|       |\n");
        printf("|      %c|\n",naipe);
        printf("\---------\n");

        i=rand()%12+1;
        if ((i==11) || (i==12) || (i==13))
            valorb=10;
        else if (i==1)
            valorb=1;
        else
            valorb=(i+1);
        naipe=rand()%3+3;
        somab=(somab+valorb);

        printf("_________\n");
        printf("|%c      |\n",naipe);
        printf("|       |\n");
        printf("|   %c   |\n",tipo[i]);
        printf("|       |\n");
        printf("|      %c|\n",naipe);
        printf("\---------\n");
        printf("\n");
        printf("Você marcou %d pontos e tem um total de %d pontos.\n",valor,soma);
        printf("O computador marcou %d pontos e tem um total de %d pontos.\n",valorb,somab);
        printf("\n");
        printf("Deseja fazer a jogada? [S/N]\n");
        scanf("%c",&op);
    }
}
  • And where is the code?

  • Vacilo, I forgot. I already updated with the code

  • Probably it is consuming the answer of the previous question in the scanf, so it never stops...

  • 1

    This program doesn’t even compile, it has several errors.

  • It compiles yes, it is compiling here in codeblocks.

  • 1

    Is that you let warnings off. For me Warning is wrong. Warning let compile but it will go wrong when it runs. So it makes no sense to accept that warnings exist. I only compile with their option to block compilation. Every professional programmer does this. Your code does not perform as you expect.

  • Here also does not compile. Warnig in C is same error.

  • 1

    No one here pointed out that using scanf is NOT considered safe and should not be used to receive user input. They gave the fish chewed but nobody here pointed out why the code does not work. You are not consuming stdin buffer. Another fflush can only be used in stdout, the use of fflush(stdin) is a violation. Disappointed with the pt OS.

  • 1

    @Vitim.us I mentioned this in my reply.

Show 4 more comments

3 answers

11

I found several errors in this code:

  • lacks the #include <time.h>;
  • has exhaust characters \ in the middle of printf;
  • cannot use '10' there in the array since '10' is 2 characters;

Be careful how you read characters from stdin as you can see in this question.

Then I added the line while ( getchar() != '\n' ); to read all the characters on stdin.

Here it is working without warnings:

#include <stdio.h>
#include <stdlib.h>
#include <time.h> 
#define max 21

int main() {
    char naipe, nome[50], op;
    char tipo[13] = {'A','2','3','4','5','6','7','8','9','T','J','Q','K'};
    int valor, valorb, soma=0, somab=0;
    int i,din=1000;
    int aposta, taposta=0;

    printf("Digite o seu nome:\n");
    scanf("%s",nome);
    op='S';

    do {
    system("cls");
    printf("Você tem %d unidades\n",din);
    printf("Escolha sua aposta inicial, %s:\n",nome);
    printf("Digite 1 para 10 unidades\n");
    printf("Digite 2 para 20 unidades\n");
    printf("Digite 3 para 50 unidades\n");
    scanf("%d",&aposta);
    } while (aposta<1 || aposta>3);
    switch (aposta) {
    case 1:
        taposta+=10;
        break;
    case 2:
        taposta+=20;
        break;
    case 3:
        taposta+=50;
        break;
    }


    while ((op=='s') || (op=='S')) {

        srand(time(NULL));
        i=rand()%12+1;
        if ((i==10) || (i==11) || (i==12) || (i==13))
            valor=10;
        else if (i==1)
            valor=1;
        else
            valor=i;
        naipe=rand()%3+3;
        soma=(soma+valor);

        printf("_________\n");
        printf("|%c      |\n",naipe);
        printf("|       |\n");
        printf("|   %c   |\n",tipo[i]);
        printf("|       |\n");
        printf("|      %c|\n",naipe);
        printf("---------\n");

        i=rand()%12+1;
        if ((i==10) || (i==11) || (i==12) || (i==13))
            valorb=10;
        else if (i==1)
            valorb=1;
        else
            valorb=(i+1);
        naipe=rand()%3+3;
        somab=(somab+valorb);

        printf("_________\n");
        printf("|%c      |\n",naipe);
        printf("|       |\n");
        printf("|   %c   |\n",tipo[i]);
        printf("|       |\n");
        printf("|      %c|\n",naipe);
        printf("---------\n");
        printf("\n");
        printf("Você marcou %d pontos e tem um total de %d pontos.\n",valor,soma);
        printf("O computador marcou %d pontos e tem um total de %d pontos.\n",valorb,somab);
        printf("\n");
        printf("Deseja fazer a jogada? [S/N]\n");

        while ( getchar() != '\n' );

        scanf("%c",&op);

        printf("Selecionou S/N: %c\n", op);
    }
}

You can see here the example

6

give a space between the quotation mark " and the % symbol in:

scanf("%s",&nome);
scanf("%d",&aposta);    
scanf("%c",&op);

being like this:

scanf(" %s",&nome);
scanf(" %d",&aposta);    
scanf(" %c",&op);

This is enough for the scanf() understand that it is a new entry.

You can also search about the function fflush(stdin) to clean the Keyboard Buffer and prevent this kind of problem from occurring.

  • 1

    Wow, just that? It worked perfectly, thanks man!

  • 1

    I would like to know who denied the answer when the questioner himself took advantage of it? I think that other answers can add a technical basis to be applied at a professional level, and should be voted positively for a good community development, but now deny the answer that met the purpose of those who asked I found too much! I leave here my vent!

  • In fact I do not know even how it solved for him but, I voted positively in his answer, I think it’s slutty to slip independent of the situation does not matter, even though I have explained better in my answer upstairs is slutty, or I give like or I leave it there.

  • 1

    @dil_oliveira I was one of those who I denied. I should have left the explanation but I didn’t. fflush can only be used with stdout, use with stdin has undefined behavior.

3

Actually the problem is in the first and second scanf, when you press ENTER there in the first scanf the string is read and sent to variable but the ' n'(ENTER) is in Buffer (The string too, but ignore these parentheses). Other things wrong: the library time.h is not included; to play this bar in the printf you have to type instead of simply and the question of '10' (2 characters) in a space in the char array.

In the second scanf you do not have this problem because you are reading an integer, only in the second scanf other ' n' is in Buffer after all you press ENTER to inform the whole.

On the third that’s the last when you put scanf("%c",&op); It reads the ' n' that is already in Buffer, so it does not stop.

Solution:

Do so, whenever you use the scanf use scanf("%SeuTipo%*c", &Variável) always put %*c that there it will read what the user informs and will discard the ' n' which is a character so %*c solves.

Problem

Assuming that the user informs invez de’S' inform 'SS' then it would read’S' and discard the other’S' and the ' n' would continue in Buffer.

Other Solutions

Usually to avoid wrong data you create a string and read everything the user tells you and put it in and then do the type validations with a regex which is simple to work, could use also fgets(which is the most recommended) or a validation such as:

For example you need the user to report only integers

#include <stdio.h>
#include <stdlib.h>
#include <string.h> //Para usar strlen()

int main(){
    char string[100];
    int a = 0, i = 0;


    printf("Informe um inteiro: ");
    scanf("%[^\n]s", &string); //Esse [^\n] Faz Ele Ler Tudo Menos O '\n'
    getchar(); // Usamos O scanf, Agora Em Baixo Dele Um getchar() Para Pegar O '\n' E Descartá-lo

    for (i = 0; i < strlen(string); i++){
        if (string[i] < '0' || string[i] > '9'){ //Ocasionaria Em Um Loop Infinito Se O Usuário Não Informar Correto.
            i = -1;
            printf("\nInforme Novamente: ");
            scanf("%[^\n]s", &string);
            getchar();
        }
    }

    // Saiu Do Loop Agora Sim O Valor De string Está correto Agora Só Converter string Em Inteiro E Colocar Em (a) Que É A Nossa Variável Do Tipo Inteiro.

    a = atoi(string); //atoi = Char To Integer
    getchar();
    return 0;
}

Browser other questions tagged

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