Failure to read char with scanf ("%c")

Asked

Viewed 3,481 times

0

Check this code to register two random matrices and then add, multiply... I want to put an option that every operation made the user has the option to quit the program, without going back to the initial menu, putting him to choose between 1 and 2 worked, but when I put to choose between S or N not the right.

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

typedef M[50][50];

void verificar_matriz (int l, int c, M matriz, int *);

void sair_menu (int *);

void receber_matriz (int l, int c, M A)
 {
int linha,coluna;
for (linha = 1; linha < (l+1) ; linha++)
{
    for (coluna = 1; coluna < (c+1); coluna++)
    {
        printf ("\nInsira o numero da Matriz[%d][%d]: ", linha, coluna);
        scanf ("%d", &A[linha][coluna]);
    }
}

system("cls");

printf ("\nMatriz: \n\n");

for (linha = 1; linha < (l+1); linha ++)
{
    for (coluna = 1; coluna < (c+1); coluna++)
    {
        printf("%d",A[linha][coluna]);
        printf("  ");
    }
    printf("\n");
}
}

void receber_matriz_ale1 (int l, int c, M matriz)
{
int linha,coluna;
srand(time(NULL));
printf ("\nMatriz Aleatoria A: \n\n");
for (linha = 1;linha < (l+1);linha++)
{
    for (coluna = 1;coluna < (c+1);coluna++)
    {
        matriz[linha][coluna] = rand()%10;
    }
}
for (linha = 1;linha < (l+1);linha++)
{
    for (coluna = 1;coluna < (c+1);coluna++)
    {
        printf("%5d",matriz[linha][coluna]);
    }
    printf("\n\n");
}
}

void receber_matriz_ale2 (int l, int c, M matriz)
{
int linha,coluna;
srand(time(NULL));
printf ("\nMatriz Aleatoria B: \n\n");
for (linha = 1;linha < (l+1);linha++)
{
    for (coluna = 1;coluna < (c+1);coluna++)
    {
        matriz[linha][coluna] = rand()%10;
    }
}
for (linha = 1;linha < (l+1);linha++)
{
    for (coluna = 1;coluna < (c+1);coluna++)
    {
        printf("%5d",matriz[linha][coluna]);
    }
    printf("\n\n");
}
}

void soma_matriz (int l, int c, M A, M B, M C)
{
int linha;
int coluna;
printf("\nMATRIZ A:\n\n");
for (linha = 1; linha < (l+1); linha++)
{
    for (coluna = 1; coluna < (c+1); coluna++)
    {
        printf("%5d",A[linha][coluna]);
    }
    printf("\n\n");
}
printf("\nMATRIZ B:\n\n");
for (linha = 1; linha < (l+1); linha++)
{
    for (coluna = 1; coluna < (c+1); coluna++)
    {
        printf("%5d",B[linha][coluna]);
    }
    printf("\n\n");
}
for (linha = 1; linha < (l+1);linha++)
{
    for (coluna = 1; coluna < (c+1);coluna++)
    {
        C[linha][coluna] = A[linha][coluna] + B [linha][coluna];
    }
}
printf ("\nMatriz resultante da Soma: \n\n");
for (linha = 1;linha < (l+1);linha++)
{
    for (coluna = 1;coluna < (c+1);coluna++)
    {
        printf("%5d",C[linha][coluna]);
    }
    printf("\n\n");
    }
}

void multiplicar_matriz (int l, int c, M A, M B, M C)
{
int linha,coluna,temp,acumula;
printf("\nMATRIZ A:\n\n");
for (linha = 1; linha < (l+1); linha++)
{
    for (coluna = 1; coluna < (c+1); coluna++)
    {
        printf("%5d",A[linha][coluna]);
    }
    printf("\n\n");
}
printf("\nMATRIZ B:\n\n");
for (linha = 1; linha < (l+1); linha++)
{
    for (coluna = 1; coluna < (c+1); coluna++)
    {
        printf("%5d",B[linha][coluna]);
    }
    printf("\n\n");
}
printf ("\nMatriz Resultante da Multiplicacao:\n\n");
for (linha = 1; linha < (l+1);linha++)
{
    for (coluna = 1; coluna < (c+1);coluna++)
    {
        acumula = 0;
        for ( temp = 0; temp < (l+1); temp++)
        {
            acumula = acumula + A[linha][temp] * B[temp][coluna];
        }
        C[linha][coluna] = acumula;
    }
}

for (linha = 1; linha < (l+1); linha++)
{
    for (coluna = 1; coluna < (c+1); coluna ++)
    {
        printf("%5d",C[linha][coluna]);
    }
    printf ("\n\n");
    }
}

void pesquisar_matriz(int l, int c, M A, M B, M SOMA, M MULT)
{

int linha, coluna;
int numero;
int controle = 0;
printf("\nDigite o numero que voce quer buscar: ");
scanf("%d",&numero);
for (linha = 1; linha < (l+1); linha++)
{
    for (coluna = 1; coluna < (c+1); coluna++)
    {
        if (numero == A[linha][coluna])
        {
            printf("\nEncontrado o numero: %d, na matriz A na posicao A[%d][%d]\n\n",numero,linha,coluna);
            controle = 1;
        }
    }
}

for (linha = 1; linha < (l+1); linha++)
{
    for (coluna = 1; coluna < (c+1); coluna++)
    {
        if (numero == B[linha][coluna])
        {
            printf("\nEncontrado o numero: %d, na matriz B na posicao B[%d][%d]\n\n",numero,linha,coluna);
            controle = 1;
        }
    }
}

for (linha = 1; linha < (l+1); linha++)
{
    for (coluna = 1; coluna < (c+1); coluna++)
    {
        if (numero == SOMA[linha][coluna])
        {
            printf("\nEncontrado o numero: %d, na matriz de SOMA na posicao SOMA[%d][%d]\n\n",numero,linha,coluna);
            controle = 1;
        }
    }
}
for (linha = 1; linha < (l+1); linha++)
{
    for (coluna = 1; coluna < (c+1); coluna++)
    {
        if (numero == MULT[linha][coluna])
        {
            printf("\nEncontrado o numero: %d, na matriz de MULTIPLICACAO na posicao MULT[%d][%d]\n\n",numero,linha,coluna);
            controle = 1;
        }
    }
}
if (controle == 0)
printf("\nNumero nao encontrado em nenhuma matriz.\n\n");
}

void verificar_matriz ( int l , int c , M matriz, int *ver)
{
int linha,coluna,controle,tamanho;
controle = 0;
for (linha = 1; linha < (l+1); linha++)
{
    for (coluna = 1; coluna < (c+1); coluna++)
    {
        if (matriz[linha][coluna] == 0)
        controle = controle + 1;
    }
}
tamanho = l*c;
if (controle == tamanho)
*ver = 2;
else
*ver = 1;
}

void sair_menu (int *saida)
{
char i;
printf("\nDeseja executar outra acao? (S/N)\n\n");
scanf ("%c",&i);
if(i == 's')
    *saida = 6;
}

int main ()
{
int l,c,op,saida;
saida = 0;
int ver;
ver = 0;
printf ("\n Digite a quantidade de linhas da matriz: ");
scanf ("%d",&l);
printf ("\n\n Digite a quantidade de colunas da matriz: ");
scanf ("%d",&c);
M matriz1,matriz2,matrizSOMA,matrizMULT;
do
{
printf("\n Escolha uma opcao: \n\n");
printf(" 1 - Cadastrar a primeira matriz aleatoria.\n\n");
printf(" 2 - Cadastrar a segunda matriz aleatoria.\n\n");
printf(" 3 - Somar duas matrizes.\n\n");
printf(" 4 - Multiplicar duas matrizes.\n\n");
printf(" 5 - Pesquisar um numero em uma matriz.\n\n");
printf(" 6 - Sair.\n\n");
scanf("%d",&op);
if (op == 1)
    receber_matriz_ale1(l,c,matriz1);
else if (op == 2)
    receber_matriz_ale2(l,c,matriz2);
else if (op == 3)
{
    verificar_matriz(l,c,matriz1,&ver);
    if (ver == 2)
    receber_matriz_ale1(l,c,matriz1);
    verificar_matriz(l,c,matriz2,&ver);
    if (ver == 2)
    receber_matriz_ale2(l,c,matriz2);
    soma_matriz(l,c,matriz1,matriz2,matrizSOMA);
    sair_menu(&saida);
    if (saida == 6)
        break;
}
else if (op == 4)
{
    verificar_matriz(l,c,matriz1,&ver);
    if (ver == 2)
    receber_matriz_ale1(l,c,matriz1);
    verificar_matriz(l,c,matriz2,&ver);
    if (ver == 2)
    receber_matriz_ale2(l,c,matriz2);
    multiplicar_matriz(l,c,matriz1,matriz2,matrizMULT);
    sair_menu(&saida);
    if (saida == 6)
        break;
}
else if (op == 5)
{
    pesquisar_matriz(l,c,matriz1,matriz2,matrizSOMA,matrizMULT);
    sair_menu(&saida);
    if (saida == 6)
        break;
}
else if (op == 6)
    break;
else
printf ("\nOpcao Invalida.\n\n");
}while (op!=6);
   return 0;
}
  • Try to isolate the problem, it’s too much code to analyze.

  • The program skips the Yes or No part of this msm? What is your OS?

  • 2

    Why don’t you put it on a switch and use the default to send this msg ? much more practical.

  • The function sair_menu is assigning 6 to the variable value saida and the programme closes when it is informed that there is a need to carry out another action.

1 answer

2


Your problem comes from scanf() previous, for example

printf ("\n\n Digite a quantidade de colunas da matriz: ");
scanf ("%d",&c);

What happens when the user chooses, for example, 8 columns is that he types "8" and "<ENTER>". The scanf() 'catches' the "8" (that puts in the variable c) and leaves the "<ENTER>" 'hanging' on the input buffer.

When next you try to read something from the buffer, this "<ENTER>" still there. If you try to read with scanf("%d", ...) the "<ENTER>" is ignored as being whitespace; if you try to read with scanf("%c", ...) the program catches the "<ENTER>" since the "%c" does not ignore blank spaces.

Suggestion #1: stop using scanf() for user input and uses fgets() (possibly followed by sscanf())

Sugestao #2: put a space before the %c to make the scanf() ignore blank spaces: scanf(" %c", ...)


PS: Always checks whether the value returned by sscanf() (or related functions) is expected

if (sscanf(tmp, "%d%d%d", &a, &b, &c) != 3) /* erro */;
  • hi, pmg, as you analyzed the AP code and know what is the root of the problem, it would be nice if you could upgrade the question because it is accumulating votes to be closed. Like, the title needs urgent help... which title would you give to describe the problem and which would help the rest of the internet to find your answer? And also, we have the freedom to adjust the text of the question in an extensive way, as long as it does not harm the original sense nor is it done to favor our answer. abs! ps: there is even a medal for those who answer and edit the question (x times)

  • 1

    Thanks old man, I just put the space before the %d in the scanf and it worked. Cool that I didn’t even imagine the problem, and now I have an idea of what it is. Thank you very much.

Browser other questions tagged

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