如果没有初始化(“mod = 0”),则此代码将进入无限循环。我无法理解为什么这个代码循环,即使我使用了getchar();擦除缓冲区。当我先键入“1”,然后键入“a”时,会出现无限循环。任何人都可以帮我理解这种情况吗?
int main()
{
srand((unsigned)time(NULL));
int mod = 0;
int val = 0;
do {
printf("\t-----------------------------\n");
printf("\t|%5s %5s %5s %5s|\n", "1.create", "2.modify", "3.print", "4.quit");
printf("\t|%15s","Input command : ");
scanf("%d", &mod);
printf("\t-----------------------------\n");
switch (mod){
case 1: random(); val++; break;
case 2: if(val != 0) { modify(); break; }
case 3: if(val != 0) { print(); break; }
default: getchar(); printf("\tUnknown Command!! Retry!! \n"); break;
}
} while (mod != 4);
}
我用Visual Studio 2015编译了这段代码。
当你输入a
时,它是mod
的无效输入,因为scanf()
期望int
为%d
。所以它没有被读入mod
。所以mod
留下了在前一次迭代中输入的mod
的值。
它进入无限循环的原因是因为scanf()
不会丢弃无效输入。因此反复尝试读取a
并失败并循环继续。
检查scanf()
的返回值并丢弃任何无效的输入。 scanf()
对于阅读用户输入而言是非常糟糕的,并且正确处理输入失败通常更难以使用它。
更好的方法是使用fgets()
读取行输入,然后使用sscanf()
解析它。
do {
...
printf("\t|%15s","Input command : ");
fgets(line, sizeof line, stdin);
char *p = strchr(line, '\n');
if(p) *p = 0; /* remove tailing newline, if present */
if( sscanf(line, "%d", &mod) != 1) {
printf("Invalid input\n");
continue;
}
printf("\t-----------------------------\n");
....
}while (mod != 4);
你的代码的问题是,一旦你输入一个有效的菜单选项的数字,变量mod总是等于你第一次输入时输入的相同数字,如果你输入了错误的输入第二次。这种行为来自于这一事实
scanf(%d, &mod);
尝试读取整数,但是当您输入“a”作为第二个选项时,输入无法从标准输入中读取整数。因此,它不会进入switch方法的默认情况,因为变量mod等于您输入的第一个有效输入的输入。