在while循环中使用scanf进行无限循环

Posted

技术标签:

【中文标题】在while循环中使用scanf进行无限循环【英文标题】:Infinite loop with scanf in while loop 【发布时间】:2018-04-05 02:51:32 【问题描述】:

我是 C 的初学者,我试图在数字中设置一个范围,但是当输入超出范围的字母时会出现无限循环(例如:p)。 如果我输入超出范围的数字,它会起作用。 我读到了,我认为这是缓冲区和函数 scanf 的问题,当我按“Enter”时,我包含了 \n。所以我试图通过用字符扫描来清洁,但没有奏效。 我还尝试在 %x 之前放置一个空格 (' '),但没有成功。 我输入无效字母后,scanf被忽略了;如果我输入了一个无效的数字,程序就会工作。

#include <stdio.h>

int main()

    int validity, pos; //validity 0:not valid, repeat the loop; validity 1: valid number
    char enter;

    while (validity == 0) 
        printf("Player1 1, type the position in hexadecimal (1 to f):\n");
        scanf(" %x%c", &pos, &enter); //here, the number pos is already in decimal

        if (pos == NULL)
            pos = 99; //if the letter typed is improper, I set 99, because is out of range
        

        if(pos<=15 && pos >=0)
            validity = 1;
         else 
            printf("Invalid number, out of range\n");
            validity = 0;
        
    

【问题讨论】:

在使用pos之前检查scanf(" %x%c", &amp;pos, &amp;enter)的返回值。至少是 1 个吗? “我试图用一个字符扫描来清理,但是没有用”——代码不这样做。如果"%x" 成功,scanf() 只会移动到"%c" 【参考方案1】:

循环中的第一次,validity 根本没有定义值。

可能是1,可能是0,可能是65,532

你应该给它一个初始值。

int validity = 0, pos; //validity 0:not valid, repeat the loop; validity 1: valid number

您将pos 声明为int;它永远不会是NULL。它将具有整数值。

这行没有意义:

if (pos == NULL)

你也应该初始化那个变量。

int validity = 0, pos = 99; //validity 0:not valid, repeat the loop; validity 1: valid number

【讨论】:

NULL 只是一个零宏。当它被预处理时,该行将显示为if (pos == 0) 编辑:虽然我同意它不应该这样写,只是指出它在技术上是有效的 你把新手弄糊涂了。 NULL 不仅是零的宏,它还具有 void* 类型,除非在特殊情况下,否则不应将 void*int 进行比较。 你是对的,我很抱歉。我保证我的意图是教学而不是迂腐【参考方案2】:

C 没有原始数据类型的默认值。因此在行中

int validity, pos;

您可能应该将validity 设置为某个默认值,例如 0,这样无论输入是什么(有效或无效),循环都至少运行一次。或者在这种情况下使用do while 循环似乎是一个更合乎逻辑的决定。

do

 //Your code
 while(validity == 0);

在这种情况下,您不必担心将默认值设置为 validity

正如@abelenky 之前指出的那样,在pos 中检查NULL 在技术上也是一个坏主意。你也可以跳过这部分

if (pos == NULL)
 
  pos = 99;

由于pos 被声明为int,如果pos 的值不在0 到15 之间,那么这部分代码会自动将其声明为无效。

if(pos<=15 && pos >=0)
 
  validity = 1;
 
else 
 
  printf("Invalid number, out of range\n");
  validity = 0;

因此没有必要再做一个块来检查它的有效性。

【讨论】:

【参考方案3】:

死循环的原因是,如果你输入一个字母,后面的“\n”会作为下一个循环中scanf(...)函数的输入。所以你可以简单地添加“getchar()”来修复它。注意忽略数字后的“\n”。

不同的是,当你输入一个超出范围的数字时,它可以用十六进制解析,你可以打印出来查看。但是字母不能(必须在 a-f 之间)。

你可以参考这个:

#include <stdio.h>
int main(int argc, char *argv[])


   int validity=0, pos=99;
   while (validity == 0)
       printf("Player1 1, type the position in hexadecimal (1 to f):\n");      
       scanf("%x", &pos); 

       if(pos<=15 && pos >=0)
          validity = 1;
       else 
          printf("Invalid number, out of range\n");
          getchar();
       
   

祝你好运。

【讨论】:

以上是关于在while循环中使用scanf进行无限循环的主要内容,如果未能解决你的问题,请参考以下文章

C : while( scanf("%d",&num) != 1 ) 无限循环

无限循环与嵌套循环

如何在 SQL Server 中组织无限 while 循环?

python循环语句

无限while循环内的Sleep()函数

我试图进行一个while循环,但循环是无限的,我不确定为什么