leo
leo

Reputation: 11

C programming loop logic error

I have some problem with the loop I trying to do. My code will prompt user for the value 1, 2 to do something, and 3 to exit. When I try to add the check for the input if it is not integer the loop will just loop non stop. I wonder is my if( !input) is wrongly used here? Can someone guide me? thanks.

do
{
    printf ("Input no\n");
    scanf ("%d", &input);

    if (input)
    {
        if ( input == 1)
        {
            printf ("do wat u wan if is 1\n");
        }

        if ( input == 2)
        {
               printf ("do wat u wan if is 2\n");
        }
    }

    else if (!input)
    {
        printf("error\n");
    }
}
while(input !=3 );

if ( input == 3)
{
    printf ("exiting\n");
}

Upvotes: 1

Views: 205

Answers (4)

rubber boots
rubber boots

Reputation: 15184

Change the first part of your code to:

...
int input;
do
{
    char line[256];
    printf("Input no\n");
    fgets(line, sizeof(line), stdin);
    sscanf(line, "%d", &input);
    if (input) 
    ...

Never ever use scanf! This is almost unusable. It may lack consistent behavior across compilers.

The problem is: if scanf() encounters an item which is not usable according to the format %d, the item will stay in the input buffer forever. You can avoid this by using %s and converting afterwards. Better: on line-input use line-reading (gets()/fgets())

If you want to detect digits/non-digits in the incoming string, you could use the isdigit() function from <ctype.h>. Your code would end up in the following form:

int input;
do {
    char line[256];
    printf("Input no\n");
    fgets(line, sizeof(line), stdin);
    if (isdigit(line[0])) {                /* check if first char is a number */
        sscanf(line, "%d", &input);        /* scan this number from string */
        if (input == 1)  {
           printf("do wat u wan if is 1\n");
        }
        if (input == 2) {
           printf("do wat u wan if is 2\n");
        }
    }
    else {
        input = 0;                        /* reset input to any value != 3 */
        printf("error\n");
    }
} while (input != 3);

Don't forget to #include <ctype.h>.

Upvotes: 0

Spikatrix
Spikatrix

Reputation: 20244

do
{
   printf ("Input no\n");
   if(scanf ("%d", &input)==1) //if `scanf` is successfull
      {
        if ( input == 1)
        {
            printf ("do wat u wan if is 1\n");
        }
         else if ( input == 2)
        {
               printf ("do wat u wan if is 2\n");
        }        
     }else //scanning an integer failed
     {
       printf("Invalid input(non-numeric value entered). Breaking loop...\n");
      scanf("%*s"); //discarding previous input
      break; //or use `continue;` for looping once more
      }
  }
while(input !=3 );
printf ("exited loop\n");

The above code will do what you want and I've also removed uneccessary stuff from it.

Upvotes: 1

2501
2501

Reputation: 25752

You have to clear the input buffer if scanf() doesn't read correctly.

int res = scanf ("%d", &input);
if( res == 0 )
{
    int clear = 0 ;
    while( ( clear = getchar() ) != EOF && clear != '\n') ;
}

In this case if res is not 1, scanf didn't read an integer and you have some characters left in stdin.

Also set input to 0 before passing it to scanf(), so that your if statement can handle the result correctly.

Upvotes: 1

simon
simon

Reputation: 1105

The problem here is not your loop, but the format specifier in your call to scanf, if you call scanf with %d it expects an integer, if it doesn't receive one it will not be happy. Try calling scanf with %c instead and convert the read character to the corresponding integer value, this fixes your problem and should be managable to do by you.

Upvotes: 0

Related Questions