所以,我正在用C语言开发一个简单的刽子手游戏,我有函数read_guess,如下所示。
void read_guess(char *guesses, char *p_current_guess)
{
int valid_guess = 0;
// Repeatedly takes input until guess is valid
while (valid_guess == 0)
{
printf(">>> ");
fgets(p_current_guess, 2, stdin);
if (!isalpha(*p_current_guess)) printf("Guesses must be alphabetic. Please try again.nn");
else
{
valid_guess = 1;
// Iterates over array of guesses and checks if letter has already been guessed
for (int i = 0; guesses[i] != ' '; i++)
{
if (guesses[i] == *p_current_guess)
{
printf("You have already guessed this letter. Please try again.nn");
valid_guess = 0;
break;
}
}
}
}
}
我已经尝试了所有标准输入函数(包括getchar(,但是对于所有这些函数,当提供大于一个字符的输入时,而不是只取第一个字符并继续前进(或再次询问(,其余的输入被"推回",下次请求输入时,无论是因为输入包含非字母字符还是下一轮开始, 其余输入将自动处理。这将对输入的每个字符重复。
我怎样才能避免这种情况?
您正在使用fgets
这很好,但不幸的是不是正确的方法...
fgets
读取到行尾或最多比请求的字符数少 1个。当然,剩余的字符留给下一个读取操作...
惯用的方法是确保阅读到行尾,无论长度如何,或者至少达到更大的长度。
-
简单,但输入时可能会失败超过 SIZE 字符:
#define SIZE 64 ... void read_guess(char *guesses, char *p_current_guess) { char line[SIZE]; int valid_guess = 0; // Repeatedly takes input until guess is valid while (valid_guess == 0) { printf(">>> "); fgets(line, SiZE, stdin); // read a line of size at most SIZE-1 p_current_guess[0] = line[0]; // keep first character p_current_guess[1] = ' '; ...
-
坚固但稍微复杂一些
/** * Read a line and only keep the first character * * Syntax: char * fgetfirst(dest, fd); * * Parameters: * dest: points to a buffer of size at least 2 that will recieve the * first character followed with a null * fd : FILE* from which to read * * Return value: dest if one character was successfully read, else NULL */ char *readfirst(dest, fd) { #define SIZE 256 // may be adapted char buf[SIZE]; char *cr = NULL; // return value initialized to NULL if nothing can be read for (;;) { if(NULL == fgets(buff, sizeof(buff), fd)) return cr; // read error or end of file if (0 == strcspn(buff, "n")) return cr; // end of file if (cr == NULL) { // first read: cr = dest; // prepare to return first char dest[0] = buff[0]; dest[1] = 0; } } }
然后,您可以在代码中简单地使用它:
void read_guess(char *guesses, char *p_current_guess) { int valid_guess = 0; // Repeatedly takes input until guess is valid while (valid_guess == 0) { printf(">>> "); fgetfirst(p_current_guess, stdin);
每次要请求输入时,都可以丢弃所有输入,直到行尾。
void skip_to_eol(FILE* f, int c)
{
while (c != EOF && c != 'n')
c = fgetc(f);
}
...
char c = getchar(); // instead of fgets
skip_to_eol(stdin, c);
你可以在 windows 上使用 getch(( 函数来获取单个字符。 这是Linux等效
的Linux 中的 getch(( 和 getche(( 等价于什么?