Scanf和循环

Dan*_*nny 2 c scanf

这里是一段代码,应该循环遍历,直到用户输入0到15之间的数字

        int input;

        do
        {

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

        }
        while (!(input>0 && input <15));
Run Code Online (Sandbox Code Playgroud)

但是,如果用户输入类似"gfggdf"的内容,则会导致循环重复一遍又一遍,并且从不提示用户再次输入...控制台看起来像这样

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)
Run Code Online (Sandbox Code Playgroud)

看完这本书之后,似乎我需要做这样的事情来防止这种情况发生.

int input, error, status;
char skip_ch;

do
{
        error = 0;

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

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

        do
        {
                scanf("%c",&skip_ch);
        }while(skip_ch != '\n');
}
while (error);
Run Code Online (Sandbox Code Playgroud)

我理解需要检查scanf状态以确保它是有效输入,我不理解内部do-while循环.我觉得这本书从来没有真正向我解释为什么需要多次调用scanf,就像扫描缓冲区填充了一堆垃圾一样,它只是通过循环遍历它一百万次来清理它您.

有人可以向我解释这个黑魔法吗?

Jon*_*ler 5

这就是为什么对于类似问题有如此多的答案,建议不要使用scanf().

此外,您应该检查返回值,scanf()因为它会告诉您何时出错 - 并且无法转换任何值.

通常推荐的解决方案是fgets()读取输入sscanf()行并在读取后解析行的组合.

示例中的第二个循环用于读取字符,包括换行符,从而重新同步scanf()和跳过任何虚假数据.这是一种冗长的做法; 它会更简单getchar():

int c;
while ((c = getchar()) != EOF && c != '\n')
    ;
Run Code Online (Sandbox Code Playgroud)

注意使用' int c;' - 类型关键不是' char'或' unsigned char'因为它必须存储所有可能的char值加上EOF.