1

So as a beginner in C and programming in general I try to write a little "hangman" game. Outside of main(), there's two functions, one that get user's attempts and one that actually check if the character is in the word, and loop until user's has found the word. Here it is:

The main.c:

/*GAME OF HANGMAN*/
#include <stdio.h>
#include <stdlib.h>
#include "functions.h"

int main(void)
{
        /*Menu*/
        int menuChoice = 0;

        printf("***********\n");
        printf("* HANGMAN *\n");
        printf("***********\n\n");
        printf("1.Play\n");
        printf("2.Quit\n");
        scanf("%d", &menuChoice);

        switch (menuChoice)
        {
        case 1:
          fflush(stdin);
          printf("Let's Play!\n");
          game();
         break;
        case 2:
          printf("Bye!\n");
          exit(0);
          break;
        default:
          printf("Error.\n");
          break;
        }

        return 0;
}



#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

functions.c:

//Get User Attempts
char userinput(void)
{
        char input = 0;

        input = getchar();//get user attempt
        input = toupper(input);//make 'input' uppercase if it's not

        while(getchar() != '\n');//read the \n to flush it from memory

        return input;//return user attempt
}

//Actuall game
void game(void)
{
        char secret[] = "HELLO";//To find
        char hiden[] = "*****";//Hidden word
        int wsize = 5;//It's size.
        do
        {
                printf("%s\n", hiden);
                printf(">");
                char try = userinput();
                int i = 0;
                for(i = 0; i < wsize; i++)
                {
                        //replace stars by found letters.
                        if(try == secret[i])
                        {
                                hiden[i] = secret[i];
                        }
                }
        }while(strcmp(hiden, secret) != 0); //Loop until found the word      

        printf("Congrats, the word was %s!\n", secret);

} `

(I don't show the "main" file/function because it only serve as a menu that redirect to game(void).)

The word to find is "hard-coded", I'll make it pick it randomly from a file when this works.

Whenever I run it, the first user's input is completely ignored, right or wrong, and from the second attempt it works properly.

I tried removing the while(getchar() != '\n') It then stop ignoring the first attempt but display ">*****" instead of just ">".

I really dont understand what's going on, any help would be much appreciated!

Sorry for my bad english and thanks in advance.

Zest
  • 99
  • 1
  • 8
  • `hiden` vs. `hidden` is a minor thing, but remember in programming every single character is important and attention to detail is a critical skill. – tadman Jul 12 '18 at 18:17
  • This code works for me if I define `int main() { game(); return 0; }` to initiate the game properly. – tadman Jul 12 '18 at 18:19
  • Not reproducible https://ideone.com/zaOCoP – n. m. could be an AI Jul 12 '18 at 18:19
  • Seems to work for me. – Christian Gibbons Jul 12 '18 at 18:20
  • 2
    Sounds like `stdin` is not empty upon first call of `userinput()`. If that's the case, `getchar()` will just read whatever is left in and move on. Did you `scanf` anything else in within your `main()`? – brainplot Jul 12 '18 at 18:21
  • 2
    *it only serve as a menu that redirect to game(void)* There is no such thing as unimportaint detail. Try building a [mcve] from the beginning to the end. – n. m. could be an AI Jul 12 '18 at 18:26
  • @brainplot yes main() ask if the user wants to play(1) or quit(2) and get the answer with a scanf. I just added 'fflush(stdin)' before calling game() but it doenst help. – Zest Jul 12 '18 at 18:33
  • `fflush(stdin)` is implementation defined, maybe in the standard even *undefined*. – Weather Vane Jul 12 '18 at 18:35
  • @n.m. I added the main() function so everything is clear! tadman thanks for the advices but I don't understand your comment about initiating the game. – Zest Jul 12 '18 at 18:38
  • 2
    `scanf("%d", &menuChoice);` leaves a newline in the input buffer. – Weather Vane Jul 12 '18 at 18:39
  • @WeatherVane how can I empty it? Or should I just avoid using scanf? – Zest Jul 12 '18 at 18:41
  • Yes, you should avoid using scanf!! – William Pursell Jul 12 '18 at 18:41
  • If you have started with `scanf` you can replace function `userinput()` with `scanf(" %c", &input); input = toupper(input);`. Notice the space before `%c`. Be careful though: it is better to work with `int` with character handling functions - you are using `char` for `getchar` and `toupper` but if you read the man pages you will find they use `int`. It's a newbie mistake to assume that a character is of type `char`. – Weather Vane Jul 12 '18 at 18:43
  • @Zest if "asking the user" requires them to input something like 'y' or 'n', you can as well avoid using `scanf()` entirely and just use a simple `getchar()` and take care of `\n` like you did in your `userinput()` function. Alternatively, you can tell `scanf()` to skip any leading whitespace character with `scanf(" %c", &buff)` or discard any trailing character with `scanf("%c%*c", &buff)`. I prefer the former but it's up to you. – brainplot Jul 12 '18 at 18:51
  • Thanks for all your help guys. @brainplot I used getchar() instead and It works great now! But I'm now curious about this scanf("%c%*c", &buff) works haha. – Zest Jul 12 '18 at 18:58
  • The target for `%c` still needs to be `char`. If it "works" it is due to endianness. – Weather Vane Jul 12 '18 at 19:00
  • @WeatherVane but I don't have any `%c` now? – Zest Jul 12 '18 at 19:28

0 Answers0