Problem in the scanf, infinite loop

Asked

Viewed 76 times

0

When I put a char on scanf the program printa lot of "height" and does not give me the chance to choose another value, only enters an infinite loop.

Code:


int main()
{
    int result;
  
    while(result < 1 || result > 8)
    {
        printf("height: ");
        scanf("%d", &result);
    }
    
    if(result >= 1 && result <= 8)
    {
        ft_mario(result);
    }
}

I’ve tried to do with char instead of int and use the result - '0' but did not give either, it does not printa dnv when wrong only for the program, and there is another way that how many characters I put it will give x print quantities of height.

I know you can take the if there and play only the function but also does not change anything.

How do I solve this problem ?

  • I’m not sure I understand, but if you use several scanf("%c", &variavel); then you’ll have trouble with garbage in the buffer.

  • wanted to make a loop until the user put the right answer

  • In case a loop read char, right? I’ll make an example here.

  • Here an example using char. I noticed I used getchar() to take out the \n of buffer.

  • i understood what you did but in case I need q o o Usario type a number and if in case he type a letter I show the scanf dnv that q ta complicating and still have the special characters ai complica more I thought of using the table ascii but tbm n had success

  • Now I understand the problem, you need to clean up the buffer. Place setbuf(stdin, NULL); or a custom function after the scanf to clean the buffer.

  • guy did it there and it worked agr the problem is when I put more than one number he takes the first number and ignores what comes dps and he was not to run with big number only from 1 to 8

  • Can you send the code as it is now? You can ask a question with it being a little clearer.

  • soon the delay, we were able to make work using the recreation of setbuf and tbm with fflush amazenando the input in a variable( input[50]) and passing it to an act,i ae only played in the function she and was successful and with the recreation of the function was good tbm, in the end until the setbuf q was giving problem worked with atoi, vlw mann this buffer stop helped a lot!!!

Show 4 more comments

2 answers

3

The problem is that when you read an integer through the entry with scanf and could not read the whole, the characters you typed are in the input, ie in the stdin. This will cause the next reading attempt to return the same error generating an infinite loop.

Interpret the result of scanf

The simplest way to solve is to test whether an integer could not be read by the return of the scanf and in that case consume a character of the input:

int main()
{
    int result;

    while(result < 1 || result > 8)
    {
        printf("height: ");
        if (scanf("%d", &result) == 0){ //se scanf deu 0 
            fgetc(stdin); //consome char na entrada
        }
    }

    if(result >= 1 && result <= 8)
    {
        ft_mario(result);
    }
}

In this solution it should be borne in mind that scanf returns the amount of entries read for the specified string. If you only have one %d then will return 1 if given to read the %d or 0 otherwise.

The fgetc used is only taking a character of the stdin without using it.

Alternatives

Alternatively, it can also read everything as a string for a wide char array, and check if it has only numbers in it. And if you have to do the interpretation at the expense of atoi or similar functions, but for the code it presents is more complicated.

2

ALWAYS test the return of scanf(). View documentation. scanf() returns a int with the total of served specifiers (specifiers are those things that have one '%' that is not followed by another. In your case it was only one: %d. scanf() returns -1 in case of error.

It’s naive to go through with the program if you haven’t read anything.

scanf() was written to read formatted input. See name: "scan formatted". The keyboard, with 105 keys of great freedom, is thus not ideal and scanf() shouldn’t be used for this. The simple is to use fgets() and read the lines, then convert to what you need.

If you want something like this

height: teste

height: outro9

height: 898797abcddff3435
8 8 7 7 3 4 3 5 

(using all possible values) can use something like

#include "stdio.h"

int main()
{
    int     result;
    char    linha[80];
    int     fim = 0;
  
    while(  fim == 0 )
    {
        printf("height: ");
        fgets( linha,sizeof(linha),stdin );
        for ( int i = 0; linha[i] != 0; i+=1 )
        {
            if( linha[i] >= '1' && linha[i] <= '8' )
            {
                printf( "%d ", linha[i] - '0');
                fim = 1;
            }
        };  // for()
        printf( "\n" );
    }
}

Browser other questions tagged

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