Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
797 views
in Technique[技术] by (71.8m points)

c - Scanf and loops

here a a piece of code that is supposed to loop over and over until the user inputs a number between 0 and 15

        int input;

        do
        {

                printf("Enter a number => ");
                scanf("%d",&input);
                printf("
 %d 
",input);

        }
        while (!(input>0 && input <15));

However if the user puts in something like "gfggdf" it results in the loop repeating over and over and over and never prompting the user for input again... the console looks like this

Enter a number =>
0
Enter a number =>
0
Enter a number =>
0
Enter a number =>
0
Enter a number =>
0
Enter a number =>
0
(looping indefinitely)

After looking through this book, it seems I need to do something like this to prevent this from happening.

int input, error, status;
char skip_ch;

do
{
        error = 0;

        printf("Enter a number => ");
        status = scanf("%d",&input);
        printf("
 %d 
",input);

        if(status!=1)
        {
                error=1;
        }
        else if(input < 0 || input >15){
                error = 1;
        }

        do
        {
                scanf("%c",&skip_ch);
        }while(skip_ch != '
');
}
while (error);

I understand needing to check for the scanf status to make sure it was valid input, What I don't understand the the inner do-while loop. I feel like the book never really explained to me why scanf needs to be called several times like that, it's like somehow the scanf buffer got filled up with a bunch of garbage and it's somehow cleaning it out by just looping through it a million times for you.

Could anyone please explain this black magic to me?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

That's why there are so many answers to similar questions that recommend not using scanf().

Also, you should check the return value from scanf() because it tells you when something has gone wrong - and no value could be converted.

The normal recommended solution is a combination of fgets() to read lines of input and sscanf() to parse the line once it is read.

The second loop in your example goes around reading the characters up to and including a newline, thus resynchronizing scanf() and skipping any bogus data. It is a long-winded way of doing it; it would be simpler to use getchar() instead:

int c;
while ((c = getchar()) != EOF && c != '
')
    ;

Note the use of 'int c;' - the type is crucially not 'char' or 'unsigned char' because it must store all possible char values plus EOF.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...