简体   繁体   English

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

[英]C - Is there a way to read a single character of user input, and not have the rest "pushed down" to the next request for input?

So, I'm working on a simple hangman game in C, and I have the function read_guess, shown below.所以,我正在用 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.\n\n");
        else
        {
            valid_guess = 1;

            // Iterates over array of guesses and checks if letter has already been guessed
            for (int i = 0; guesses[i] != '\0'; i++)
            {
                if (guesses[i] == *p_current_guess)
                {
                    printf("You have already guessed this letter. Please try again.\n\n");
                    valid_guess = 0;
                    break;
                }
            }
        }
    }
}

I've tried all the standard input functions (including getchar), but with all of them, when an input larger than one character is supplied, instead of taking just the first character and moving on (or asking again), the rest of the input is "pushed back", and the next time input is requested, whether it be because the input contained a non-alphabetic character or the next round begins, the rest of the input is automatically processed.我已经尝试了所有标准输入函数(包括 getchar),但是对于所有这些函数,当提供大于一个字符的输入时,而不是只取第一个字符并继续(或再次询问),其余的输入被“推回”,下次请求输入时,无论是因为输入包含非字母字符还是下一轮开始,其余的输入都会自动处理。 This repeats for each character of the input.这对输入的每个字符重复。

How can I avoid this?我怎样才能避免这种情况?

You can discard all input until end-of-line, each time you want to ask for input.每次您想要求输入时,您都可以放弃所有输入,直到行尾。

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);

You are using fgets which is good, but unfortunately not the right way...您使用的fgets很好,但不幸的是不是正确的方法......

fgets reads up to an end of line or at most 1 less the the number of character asked. fgets读取到行尾或最多比请求的字符数少 1 And of course remaining characters are left for the next read operation...当然,剩余的字符将留给下一个读取操作......

The idiomatic way would be to ensure reading up to the end of line, whatever the length, or at least up to a much larger length.惯用的方法是确保读取到行尾,无论长度如何,或者至少达到更大的长度。

  1. Simple but could fail in more than SIZE characters on input:简单但在输入超过 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] = '\\0'; ...
  2. Robust but slightly more complex健壮但稍微复杂一点

    /** * 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; } } }

    You can then use it simply in your code:然后你可以简单地在你的代码中使用它:

     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);

You can use getch() function on windows to get single character.您可以在 Windows 上使用 getch() 函数来获取单个字符。 and this is linux equivalent这是 linux 等价的

What is the equivalent to getch() & getche() in Linux? Linux 中 getch() 和 getche() 的等价物是什么?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM