scanf 无法处理无效输入
scanf not working on invalid input
第一个 scanf()
中的字符输入,第二个 运行 中没有。 getchar()
对“重试”输入无效。它会跳过输入 Would you like to play again? (Y/N)? 貌似应该是your_choice
拿了字再查,其实字被ch
拿了。是什么导致它像这样工作以及如何解决该问题。我试过重新初始化变量但没有用。
#include <stdio.h>
void choice(int);
int main() {
char ch;
int random, your_choice;
do {
srand(time(NULL));
system("cls");
printf("** 0 is for Rock **\n");
printf("** 1 is for Scissors **\n");
printf("** 2 is for Lizard **\n");
printf("** 3 is for Paper **\n");
printf("** 4 is for Spock **\n");
printf("\nEnter your choice here:");
scanf("%d", &your_choice);
random = rand() % 5; //random number between 0 & 4
if ((your_choice >= 0) && (your_choice <= 4)) {
//choice printer omitted for this post
if ((random == ((your_choice + 1) % 5)) || (random == ((your_choice + 2) % 5)))
printf("\n\n... and you win!!!\n");
else if ((random == ((your_choice + 3) % 5)) || (random == ((your_choice + 4) % 5)))
printf("\n\n... and you lose!!!\n");
else if (random == your_choice)
printf("\n\nUnfortunately, it's a tie!\n");
} else
printf("\nWell, this is wrong! Try again with a number from 0 to 4!!\n");
printf("\nWould you like to play again? (Y/N)?: ");
scanf(" %c", &ch);
} while (ch == 'y' || ch == 'Y');
return 0;
}
如果用户输入不能转换为数字的字符,scanf("%d", &your_choice);
returns 0 和 your_choice
保持不变,因此未初始化。行为未定义。
您应该对此进行测试并以这种方式跳过有问题的输入:
if (scanf("%d", &your_choice) != 1) {
int c;
/* read and ignore the rest of the line */
while ((c = getchar()) != EOF && c != '\n')
continue;
if (c == EOF) {
/* premature end of file */
return 1;
}
your_choice = -1;
}
解释:
scanf()
returns 成功转换的次数。如果用户输入的是数字,则转换存储为your_choice
和scanf()
returns 1,如果用户输入的不是数字,如AA
, scanf()
将有问题的输入留在标准输入缓冲区中,returns 0,最后如果到达文件末尾(用户在 windows 中输入 ^Z 或在 unix 中输入 ^D), scanf()
returns EOF
.
如果输入未转换为数字,我们进入 if
语句的主体:使用 getchar()
一次消耗一个字节的输入,直到读取文件末尾或换行符。
如果getchar()
返回EOF
,我们已经读取了整个输入流,不需要提示用户进行更多输入,你可能想在之前输出一条错误信息返回错误代码。
否则,将 your_choice
设置为 -1
,这是一个无效值,因此代码读取会出现错误并提示进一步输入。
读取并丢弃违规输入是必要的:如果您不这样做,下一个输入语句 scanf(" %c", &ch);
将读取违规输入的第一个字符,而不是等待用户输入以响应 Would you like to play again? (Y/N)?:
提示。这是对您观察到的行为的解释。
第一个 scanf()
中的字符输入,第二个 运行 中没有。 getchar()
对“重试”输入无效。它会跳过输入 Would you like to play again? (Y/N)? 貌似应该是your_choice
拿了字再查,其实字被ch
拿了。是什么导致它像这样工作以及如何解决该问题。我试过重新初始化变量但没有用。
#include <stdio.h>
void choice(int);
int main() {
char ch;
int random, your_choice;
do {
srand(time(NULL));
system("cls");
printf("** 0 is for Rock **\n");
printf("** 1 is for Scissors **\n");
printf("** 2 is for Lizard **\n");
printf("** 3 is for Paper **\n");
printf("** 4 is for Spock **\n");
printf("\nEnter your choice here:");
scanf("%d", &your_choice);
random = rand() % 5; //random number between 0 & 4
if ((your_choice >= 0) && (your_choice <= 4)) {
//choice printer omitted for this post
if ((random == ((your_choice + 1) % 5)) || (random == ((your_choice + 2) % 5)))
printf("\n\n... and you win!!!\n");
else if ((random == ((your_choice + 3) % 5)) || (random == ((your_choice + 4) % 5)))
printf("\n\n... and you lose!!!\n");
else if (random == your_choice)
printf("\n\nUnfortunately, it's a tie!\n");
} else
printf("\nWell, this is wrong! Try again with a number from 0 to 4!!\n");
printf("\nWould you like to play again? (Y/N)?: ");
scanf(" %c", &ch);
} while (ch == 'y' || ch == 'Y');
return 0;
}
如果用户输入不能转换为数字的字符,scanf("%d", &your_choice);
returns 0 和 your_choice
保持不变,因此未初始化。行为未定义。
您应该对此进行测试并以这种方式跳过有问题的输入:
if (scanf("%d", &your_choice) != 1) {
int c;
/* read and ignore the rest of the line */
while ((c = getchar()) != EOF && c != '\n')
continue;
if (c == EOF) {
/* premature end of file */
return 1;
}
your_choice = -1;
}
解释:
scanf()
returns 成功转换的次数。如果用户输入的是数字,则转换存储为your_choice
和scanf()
returns 1,如果用户输入的不是数字,如AA
,scanf()
将有问题的输入留在标准输入缓冲区中,returns 0,最后如果到达文件末尾(用户在 windows 中输入 ^Z 或在 unix 中输入 ^D),scanf()
returnsEOF
.如果输入未转换为数字,我们进入
if
语句的主体:使用getchar()
一次消耗一个字节的输入,直到读取文件末尾或换行符。如果
getchar()
返回EOF
,我们已经读取了整个输入流,不需要提示用户进行更多输入,你可能想在之前输出一条错误信息返回错误代码。否则,将
your_choice
设置为-1
,这是一个无效值,因此代码读取会出现错误并提示进一步输入。
读取并丢弃违规输入是必要的:如果您不这样做,下一个输入语句 scanf(" %c", &ch);
将读取违规输入的第一个字符,而不是等待用户输入以响应 Would you like to play again? (Y/N)?:
提示。这是对您观察到的行为的解释。