0

I was given a homework assignment which tasked us with creating a simple hangman game. Below is the code I have. I am currently trying to use if else with getchar() to ask the user to input a lowercase letter and see if it matches one of the letters in the word they are supposed to guess. From my very limited experience the code I have should work and when I step through the program it appears as if it should run properly, but when I actually run the program it seems to skip over the second getchar(). Anyone have any suggestions or help?

#include "stdio.h"
#include "math.h"

int main(void) {
    int(a);
    int(b);
    float(x);
    float(c);
    float(e);

    int word[4] = {116, 101, 115, 116};
    int guess[4];

    c == 0;
    a == 0;
    b == 0;

    printf("Welcome to Hangman\n");
    printf("Input a word--one lower case letter at a time\n");
    printf("Enter Guess: ");

    x = getchar();

    if (x > 122) {
        printf(" Error, character must be a lowercase letter");
    } else
    if (x < 97) {
        printf(" Error, character must be a lowercase letter");
    } else
    if (x == 116) {
        printf("t is correct\n");

        printf("%d", word[0]);
        printf(" _");
        printf(" _");
        printf(" %d ", word[3]);

        e = getchar();

        if (e == 101) {
            printf("e is correct\n");

            printf("%d", word[0]);
            printf(" %d", word[1]);
            printf(" _");
            printf(" %d ", word[3]);
        } else
        if (e == 115) {
            printf("s is correct\n");

            printf("%d", word[0]);
            printf(" _");
            printf(" %d", word[2]);
            printf(" %d", word[0]);
        } else {
            printf(" You guessed wrong");
        }
    } else
    if (x == 101) {
        printf("e is correct\n");
        printf("_");
        printf(" %d", word[1]);
        printf(" _");
        printf(" _ ");
    } else
    if (x == 115) {
        printf("s is correct\n");

        printf("_");
        printf(" _");
        printf(" %d", word[2]);
        printf(" _ ");
    } else {
        printf(" You guessed wrong");
    }
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • 2
    What is `int(a);` ... Your declarations are incorrect for starters... Try `int a;` Also `a == 0;` is a comparison of `a` to zero, **not** an *assignment of zero to* `a`, try `a = 0;` – David C. Rankin Feb 24 '17 at 08:27
  • 3
    This is garbage code. – Paul Ogilvie Feb 24 '17 at 08:28
  • 1
    `c == 0;` et al. don't do anything. – Biffen Feb 24 '17 at 08:28
  • 2
    There are several problems here. But your main question is about `getchar()`. The answer is that you're forgetting about the NEWLINE character: [Clarification needed regarding getchar() and newline](http://stackoverflow.com/questions/12544068/clarification-needed-regarding-getchar-and-newline) – paulsm4 Feb 24 '17 at 08:29
  • 2
    You mustn't write a separate if statement for each character. That's just not how to do it. If you find yourself writing the same line of code a second time chances are you're doing something wrong. – Biffen Feb 24 '17 at 08:30
  • 1
    You should drop those useless blank lines. Not all, only the useless ones. – Jabberwocky Feb 24 '17 at 08:33
  • 1
    Why are you using an integer array? just use `char word[5] = "test"`. And think about your code. Use a second array to store the correct guesses and iterate over the field of characters in order to check the input. – LittleByBlue Feb 24 '17 at 08:38
  • @DavidC.Rankin it is valid to add parentheses around the name in declarations, but otherwise this code is pure garbage. – Antti Haapala -- Слава Україні Feb 24 '17 at 09:48

2 Answers2

2

When you input a character that you want getchar to read, you end it with the Enter key right? That Enter key will also be put into the input buffer of stdin (which is what getchar reads from) as a newline, '\n'.

That means for each input you give, you actually input two characters.

You need to skip that newline. This can easily be done by just adding a second getchar after the first, like for example

x = getchar();
getchar();  // Read the newline from the Enter key
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • 2
    And `x` should be type `int` so you can check `if (x == EOF) { return 1; }` on the user canceling input **before** your second `getchar` or you will be blocking on the second `getchar`. – David C. Rankin Feb 24 '17 at 08:34
0

There is already a good answer, but to clarify the problem a little bit more, here is a simple piece of code. The function get_character will return the first entered character and consume all following characters until the next '\n'.

It is not going to block if one character is EOF.

#include<stdio.h>
int get_character(void);

int main(void)
{
        printf("character > ");
        int c = get_character();
        while(c != EOF && c != 'q')
        {
                printf("You entered %c\n", c); 
                printf("character > ");
                c = get_character();
        }
}

int get_character(void)
{
        int c = getchar(), next_c;
        if(c == EOF)
        {
                return EOF;
        }
        next_c = getchar(); // consume all \n
        while(next_c != '\n' && next_c != EOF)
        {
                fprintf(stderr, "WARNING: consumed non-newline character: 0x%x\n", next_c); 
                next_c = getchar(); 
        }
        return c;
}

By the way: You are able to solve the hangman way faster:

int get_character(void);
#define MAX_TRIALS 3
#define WORD_LEN 4

int main(void)
{
    char word[WORD_LEN + 1] = "test";
    char correct[WORD_LEN] = {0, 0, 0, 0};
    int trials = 0;
    while(1)
    {
        if(trials > MAX_TRIALS)
        {
            printf("You failed. The word was: %s\n", word);
            return 0;
        }

        printf("character > ");
        int c = get_character();
        if(c == EOF)
        {
            printf("bye\n");
            return 0;
        }

        int i, this_char_correct = 0;
        for(i = 0; i < WORD_LEN; i++)
        {
            if(c == word[i])
            {
                correct[i] = 1;
                this_char_correct = 1;
            }
            if(correct[i])
            {
                printf("%c", word[i]);
            }
            else
            {
                printf("_");
            }
        }
        if(!this_char_correct)
        {
            trials++;
        }
        int word_done = 1;
        for(i = 0; i < WORD_LEN; i++)
        {
            word_done &= correct[i];
        }
        if(! word_done)
        {
            printf("\nYou have %d trials left\n", WORD_LEN - trials);
        }
        else
        {
            printf("\nYou got it.\n");
            return 0;
        }
    }
}

This is just a piece of proof-of-concept code there might be way more elegant ways to solve this.

LittleByBlue
  • 436
  • 9
  • 18