运行 使用 scanf 进入无限循环
Running into infinite loop with scanf
所以我有一些这样的代码(请注意这是在 C89 中):
void inputChoice(int* choicePtr)
{
int choice;
printf(BLUE "\nINPUT: " RESET); /* Print input using the ansi colour code for Blue. */
scanf("%d", &choice); /* Parse the choice. */
while ((choice < 1) && (choice > 5)) /* Loop until choice is one of the menu options. */
{
/* Request for a valid menu option, printing this using the ansi colour code for Red, then resetting back to the default colour. */
printf(RED "\nMenu Selection must be between (1 and 5) inclusive. \nPlease Re-enter. \n" RESET);
scanf("%d", &choice); /* Parse the choice. */
}
*choicePtr = choice; /* Set the choice pointer to the valid choice after validation. */
}
选择哪个。它适用于整数。但是如果有人输入其他任何东西,例如一个字符。它无限循环。
我想以某种方式检查是否输入了字符。
我尝试过的一种方法是添加这个来检查是否输入了字符,因为如果没有正确扫描,整数将为 0。
如下所示,但这也不起作用:
scanf("%d", &choice);
while (choice == 0)
{
printf("Invalid Choice Re-enter.");
scanf("%d", &choice);
}
表达式
while ((choice < 1) && (choice > 5))
永远不会为真,因为 choice
不能同时大于 5
和小于 1
。
您需要:
while (choice < 1 || choice > 5)
scanf
将尝试解析缓冲区中是否有任何内容但无法解析,它将继续尝试导致无限循环,因为缓冲区中的任何内容都将保留在那里直到成功解析.
由于 scanf
将 return 0
如果没有参数被解析,您可以使用该信息来清除缓冲区以删除导致无限循环的原因:
int choice = 0;
int c;
int scanned;
//...
if ((scanned = scanf("%d", &choice)) == EOF){ //check for EOF return
puts("Unexpected error.");
//error treatment is upt to you, I would avoid the loop
*choicePtr = scanned;
return;
}
if (scanned == 0) {
while ((c = fgetc(stdin)) != '\n' && c != EOF){}
}
在两个 scanf
中。
考虑到评论中的评论,这里是一个修改版本:
/* reading an input choice between 1 and 5 or -1 on error */
void inputChoice(int *choicePtr) {
int choice;
printf(BLUE "\nINPUT: " RESET); /* Print input using the ansi colour code for Blue. */
for (;;) {
int res = scanf("%d", &choice); /* Parse the choice. */
if (res == EOF) {
printf(RED "unexpected end of file\n" RESET);
choice = -1;
break;
}
if (res == 0) {
int c;
while ((c = getchar()) != EOF && c != '\n')
continue;
printf(RED "invalid entry\n" "Please Re-enter.\n" RESET);
continue;
}
if (choice >= 1 && choice <= 5) {
break;
}
/* Loop until choice is one of the menu options. */
/* Request for a valid menu option, printing this using the ansi
colour code for Red, then resetting back to the default colour. */
printf(RED "\nMenu Selection must be between (1 and 5) inclusive.\n"
"Please Re-enter.\n" RESET);
}
/* Set the choice pointer to the valid choice after validation. */
*choicePtr = choice;
}
所以我有一些这样的代码(请注意这是在 C89 中):
void inputChoice(int* choicePtr)
{
int choice;
printf(BLUE "\nINPUT: " RESET); /* Print input using the ansi colour code for Blue. */
scanf("%d", &choice); /* Parse the choice. */
while ((choice < 1) && (choice > 5)) /* Loop until choice is one of the menu options. */
{
/* Request for a valid menu option, printing this using the ansi colour code for Red, then resetting back to the default colour. */
printf(RED "\nMenu Selection must be between (1 and 5) inclusive. \nPlease Re-enter. \n" RESET);
scanf("%d", &choice); /* Parse the choice. */
}
*choicePtr = choice; /* Set the choice pointer to the valid choice after validation. */
}
选择哪个。它适用于整数。但是如果有人输入其他任何东西,例如一个字符。它无限循环。 我想以某种方式检查是否输入了字符。
我尝试过的一种方法是添加这个来检查是否输入了字符,因为如果没有正确扫描,整数将为 0。
如下所示,但这也不起作用:
scanf("%d", &choice);
while (choice == 0)
{
printf("Invalid Choice Re-enter.");
scanf("%d", &choice);
}
表达式
while ((choice < 1) && (choice > 5))
永远不会为真,因为 choice
不能同时大于 5
和小于 1
。
您需要:
while (choice < 1 || choice > 5)
scanf
将尝试解析缓冲区中是否有任何内容但无法解析,它将继续尝试导致无限循环,因为缓冲区中的任何内容都将保留在那里直到成功解析.
由于 scanf
将 return 0
如果没有参数被解析,您可以使用该信息来清除缓冲区以删除导致无限循环的原因:
int choice = 0;
int c;
int scanned;
//...
if ((scanned = scanf("%d", &choice)) == EOF){ //check for EOF return
puts("Unexpected error.");
//error treatment is upt to you, I would avoid the loop
*choicePtr = scanned;
return;
}
if (scanned == 0) {
while ((c = fgetc(stdin)) != '\n' && c != EOF){}
}
在两个 scanf
中。
考虑到评论中的评论,这里是一个修改版本:
/* reading an input choice between 1 and 5 or -1 on error */
void inputChoice(int *choicePtr) {
int choice;
printf(BLUE "\nINPUT: " RESET); /* Print input using the ansi colour code for Blue. */
for (;;) {
int res = scanf("%d", &choice); /* Parse the choice. */
if (res == EOF) {
printf(RED "unexpected end of file\n" RESET);
choice = -1;
break;
}
if (res == 0) {
int c;
while ((c = getchar()) != EOF && c != '\n')
continue;
printf(RED "invalid entry\n" "Please Re-enter.\n" RESET);
continue;
}
if (choice >= 1 && choice <= 5) {
break;
}
/* Loop until choice is one of the menu options. */
/* Request for a valid menu option, printing this using the ansi
colour code for Red, then resetting back to the default colour. */
printf(RED "\nMenu Selection must be between (1 and 5) inclusive.\n"
"Please Re-enter.\n" RESET);
}
/* Set the choice pointer to the valid choice after validation. */
*choicePtr = choice;
}