繁体   English   中英

Scanf和循环

[英]Scanf and loops

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

        int input;

        do
        {

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

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

但是,如果用户输入类似“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)

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

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);

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

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

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

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

通常推荐的解决方案是fgets()读取输入行和sscanf()的组合,一旦读取就解析行。

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

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

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

原代码循环下去,因为无效的数据(以下简称“gfggdf”) 从输入缓冲区中取出时scanf函数无法将其转换为整数-它留在输入缓冲器,因此scanf函数下次调用着眼于同数据,(当然)仍然无法将其转换为整数,因此循环再次执行,结果仍然没有改变。

的:

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

只需一次读取一个字符(并忽略它),直到它到达行尾。 如果你想在没有循环的情况下去除输入缓冲区中的垃圾,你可以使用类似: scanf("%*[^\\n]");

另一种可能(可能更多)被广泛使用的可能性是从读取整行开始,然后尝试转换行中的内容。 无论是否转换,您已经读取了所有数据到行尾,因此无论转换是否有效,下一行读取/转换的下一次尝试都将从下一行开始。 这确实有一个潜在的缺点:如果你有一个很的输入线,你最终可能会读取并存储大量你没有实际用途的数据。 这很少是一件大事,但你仍应该意识到这一点。

首先,避免使用scanf() ,而是使用fgets()

评估您的情况(第一个代码)。 0 > 0false 0 < 15true false && truefalse !falsetrue 这就是它无限循环的原因。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM