我试图用一个简单的游戏做一个程序,让用户猜出这个数字。我的代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX 30
#define TRYING 5
void guessnumber(int, int, int *);
int main(void) {
int mytry = 1;
guessnumber(MAX, TRYING, &mytry);
if (mytry <= TRYING)
printf("Congratulations! You got it right in %d tries\n", mytry);
else
printf("Unfortunately you could not guess the number in the number of tries predefined\n");
printf("End\n");
return EXIT_SUCCESS;
}
void guessnumber(int _n, int _m, int *_mytry) {
srandom(time(NULL));
int generated = 0, mynum = 0, test = 0;
generated = rand() % (_n + 1);
printf("Welcome to \"Guess the number\" \n");
printf("A number between 0 and %d was generated\n", _n);
printf("Guess the number:\n");
while (*_mytry <= TRYING) {
test = scanf(" %d", &mynum);
if (test != 1 || mynum < 0 || mynum > MAX)
printf("ERROR: please enter a valid number \n");
else
if (mynum > generated)
printf("Wrong! The number your trying to guess is smaller\n");
else
if (mynum < generated)
printf("Wrong ! The number your trying to guess is bigger\n");
else
break;
*_mytry = *_mytry + 1;
}
}
好的,现在该程序工作正常,除了一件事:scanf
测试。
如果我尝试输入一个超出我的范围的数字(负数或高于我的上限),它会起作用,但如果我试图输入一个字母,它就会失败。它的作用是打印错误_m次的消息,然后打印出来#34;不幸的是你无法猜测预定义次数的数量&#34;和&#34;结束&#34;。
我做错了什么,如何解决这个问题?
答案 0 :(得分:2)
如果输入了某个字符,您就会尝试正确检测它
if(test!=1 ......
但你没有采取任何措施来纠正它。
详细说明,一旦输入了一个字符,就会导致匹配失败。因此输入不被消耗,循环回落到起源位置,只有循环计数器增加。现在,先前的输入未被消耗,再次被送到scanf()
导致失败。
这样,循环继续,直到循环条件为假。此外,对于scanf()
的每次点击,由于未使用的数据已经存在于输入缓冲区中,因此不会给出新的提示。
解决方案:当您遇到故障时,需要清除现有内容的输入缓冲区。你可以做点什么
while ((c = getchar()) != '\n' && c != EOF);
清除现有内容的缓冲区。
答案 1 :(得分:1)
输入字母时,scanf()
会将字母留在输入流中,因为它与%d
转换说明符不匹配。最简单的方法是使用getchar()
删除不需要的字符:
if (test != 1) {
getchar();
}
更好的解决方案是使用fgets()
获取输入行,使用sscanf()
来解析输入:
char buffer[100];
while (*_mytry<=TRYING)
{
if (fgets(buffer, sizeof buffer, stdin) == NULL) {
fprintf(stderr, "Error in fgets()");
exit(EXIT_FAILURE);
}
test=sscanf(buffer, "%d", &mynum);
if(test!=1 || mynum<0 || mynum>MAX)
printf ("ERROR: please enter a valid number \n");
else if(mynum>generated)
printf("Wrong! The number your trying to guess is smaller\n");
else if(mynum<generated)
printf("Wrong ! The number your trying to guess is bigger\n");
else
break;
*_mytry=*_mytry+1;
}
在上面的代码中,请注意已从格式字符串中删除了前导空格。格式字符串中的前导空格会导致scanf()
跳过前导空格,包括换行符。例如,当第一个转换说明符为%c
时,这很有用,因为任何先前的输入都可能留下了换行符。但是,%d
转换说明符(以及大多数其他转换说明符)已经跳过前导空格,因此这里不需要它。
此外,您的代码有srandom()
而不是srand()
;并且对srand()
的调用应该只进行一次,并且可能应该在main()
的开头。并且,带有前导下划线的标识符在C中保留,因此您应更改名称_m
,_n
和_mytry
。