Dan
Dan

Reputation: 33

scanf skipped after reading in integer in C, in while loop

I have a section of code where I check the input to scanf is valid. i.e. if scanf returns a non zero positive number. This is part of my code:

while(scanf(" %d",&choice)<=0){
        printf("Incorrect value entered, please re-enter\n");
    }

Where “choice” is an integer.

Every time I run this code, the compiler skips past the scanf after the while loops is executed. I get an output like this:


Welcome to the Predator/Prey Calculator

Please enter your name

Dan Hi Dan

Please choose one of the following options: 1. Calculate the evolution of a TYPICAL predator and prey system 2. Calculate the evolution of a SPECIFIC predator and prey system 3. Calculate the evolution of a CUSTOM predator and prey system 0. Quit a Incorrect value entered, please re-enter Incorrect value entered, please re-enter Incorrect value entered, please re-enter Incorrect value entered, please re-enter Incorrect value entered, please re-enter Incorrect value entered, please re-enter Incorrect value entered, please re-enter Incorrect value entered, please re-enter Incorrect value entered, please re-enter Incorrect value entered, please re-enter Incorrect value entered, please re-enter Incorrect value entered, please re-enter Incorrect value entered, please re-enter Incorrect value entered, please re-enter Incorrect value entered, please re-enter

Incorrect value entered, please re-enter

Could you explain why this happens! I can’t seem to find any answers on the internet specific to reading in integers.

Many thanks,

Upvotes: 0

Views: 669

Answers (3)

igon
igon

Reputation: 3046

The problem with your code is that in case the user does not input a number your program will loop forever. This is because scanf will repeatedly try to parse the same string and keep failing. What you have to do is to match whatever the user has written and then ask again for a number:

#include<stdio.h>

int main(){
    int choice;
    while(scanf("%d",&choice) <= 0){
        scanf("%*s"); // this will parse anything the user has written
        printf("Incorrect value entered, please re-enter\n");
    }
    return 0;
}

The * in the scanf format string is the assignment suppression character, from scanf man page:

'*' assignment-suppression character: scanf() reads input as directed by the conversion specification, but discards the input. No corresponding pointer argument is required, and this specification is not included in the count of successful assignments returned by scanf().

Upvotes: 2

Weather Vane
Weather Vane

Reputation: 34585

EDIT First complaint is that scanf() returns the number of fields successfully converted. The next problem is that scanf leaves unconverted characters in the input, and will try to convert these same characters again. After a duff input, you can clear the input like this:

#include <stdio.h>

#define MAXCHOICE 42

int main(void)
{
    int choice, ch;
    while(scanf("%d",&choice) != 1 || choice < 1 || choice > MAXCHOICE){
        printf("Incorrect value entered, please re-enter\n");
        while((ch = getchar(stdin)) != '\n');     // clear the input
    }
    printf("Choice %d\n", choice);
    return 0;
}

Program session:

100
Incorrect value entered, please re-enter
a
Incorrect value entered, please re-enter
5
Choice 5

Upvotes: 1

Michi
Michi

Reputation: 5297

Probably this is what you need:

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

int main(void){
    int choice,repeat = 0;

    do{
        printf("Give a Number: ");
        if((scanf("%d",&choice)) != 1){
            printf("ErrorFix it!\n");
            exit(1);
        }else{
            if(choice > 0){
                printf("OK\n");
                repeat = 0;
            }else{
                printf("Incorrect value entered, please re-enter\n");
                repeat = 1;
            }
        }
    }while(repeat == 1);

    printf("Your typed %d\n",choice);
    return 0;
}

Output:

Give a Number: 0
Incorrect value entered, please re-enter

Give a Number: -5
Incorrect value entered, please re-enter

Give a Number: 10
OK
Your typed 10

Upvotes: 0

Related Questions