C - 有没有办法读取用户输入的单个字符,而不是将其余字符"pushed down"到下一个输入请求?



所以,我正在用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个。当然,剩余的字符留给下一个读取操作...

惯用的方法是确保阅读到行尾,无论长度如何,或者至少达到更大的长度。

  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] = '';
    ...
    
  2. 坚固但稍微复杂一些

    /**
    * 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(( 等价于什么?

相关内容

  • 没有找到相关文章

最新更新