使用 "while" 语法的 scanf("%d",a) 绕过 scanf
scanf("%d",a) with a "while" grammar bypass the scanf
如果没有初始化 ("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()
期望 %d
的 int
。所以不是读成mod
。所以 mod
留下了在上一次迭代中输入的 mod
的值。
它进入无限循环的原因是因为 scanf()
不丢弃无效输入。因此反复尝试读取 a
并失败并继续循环。
检查 scanf()
的 return 值并丢弃任何无效输入。
scanf()
对于读取用户输入来说是出了名的糟糕,正确处理输入失败通常更难使用它。
更好的方法是使用 fgets()
and then parse it using 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 等于您输入的第一个有效输入的输入。
如果没有初始化 ("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()
期望 %d
的 int
。所以不是读成mod
。所以 mod
留下了在上一次迭代中输入的 mod
的值。
它进入无限循环的原因是因为 scanf()
不丢弃无效输入。因此反复尝试读取 a
并失败并继续循环。
检查 scanf()
的 return 值并丢弃任何无效输入。
scanf()
对于读取用户输入来说是出了名的糟糕,正确处理输入失败通常更难使用它。
更好的方法是使用 fgets()
and then parse it using 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 等于您输入的第一个有效输入的输入。