Resolved [C] What happens to my char array?

Discussion in 'Mac Programming' started by confuded, Apr 20, 2011.

  1. confuded, Apr 20, 2011
    Last edited: Apr 21, 2011

    macrumors newbie

    Apr 20, 2011

    Please consider the following SHORT code:

    #include <stdio.h>
    #include <time.h>
    #include <stdlib.h>
    #include <stdbool.h>
    #define kCups 3
    int RandomNumber(int l_limit, int u_limit);
    void ClearArray(bool array[], int size);
    int main (int argc, const char * argv[]){
        //initialise array of cups (boolean)
        bool cups[kCups];
        //initialise menu loop
        bool exit = false;
            printf("There are %d cups. One of them contains the ball.\n"
                   "Which cup contains the ball?\n", kCups);
            //play again?
            bool validAnswer = false;
                printf("Play the game again?\n");
                char answer[4];
                fgets(answer, 4, stdin);
                    case 'y': case 'Y':
                        validAnswer = true;
                    case 'n': case 'N':
                        validAnswer = true;
                        exit = true;
                        printf("Please enter a valid answer!\n");
        return 0;
    void ClearArray(bool array[], int size){
        for(int i = 0; i < size; i++)
            array[i] = false;
    If you run the program the first time around and type in 'yes' when asked, it will go back and do what it's suppose to... The second time it gets to the switch statement NO MATTER what you type - the switch goes do default!

    I've run the code in Xcode 4 under gdb and looked at the answers array the first and the consecutive times around... At first all seems normal, but then the array is filled up with jumble!

    Does the fgets() fail? Does the array needs to be cleared or something?

    Thanks in advance!

  2. macrumors 68040

    Feb 2, 2008
    My guess is that a new line character is left in the buffer. So the second time around, fgets gets '\n' which match nothing but the default. This makes sense with the 'Yes' alternative as well since the string consumes all space you have i.e 'Y', 'e', 's', '\0'. Try making the answer into answer[5].
  3. macrumors 604

    Aug 9, 2009
    I concur.

    The posted code works fine if you only enter short responses, such as "y" or "n". It only malfunctions with long responses: e.g. try it with "yarrow" or "yesterday" or "you must be joking".

    Better input checking would improve results even more. The key is to check for a newline at the end of the fgets() result. If you don't see a newline, then it means a complete line wasn't read, so you should repeatedly call fgets() until a newline IS read. This newline indicates the end of the line, i.e. the end of "yarrow" or "yesterday" or "you must be joking". If you're smart, you'll put this in a separate function, which you can then reuse in other programs that have similar input requirements.
  4. Bill McEnaney, Apr 21, 2011
    Last edited: Apr 21, 2011

    macrumors 6502

    Apr 29, 2010
    Since you check only answer[0], to avoid the newline problem, why not declare answer as a character variable, not as a string?
  5. confuded, Apr 21, 2011
    Last edited: Apr 21, 2011

    thread starter macrumors newbie

    Apr 20, 2011
    subsonix, the suggestion works temporarily for my programing practice to allow for answer to be 5 chars long, though if I enter something longer than 'yes' the problem still occurs...

    chown33, I am a little confused on how this solves the problem...
    The inout still REMAINS in the stdin buffer...

    If I type in 'yess' the first time around and press enter, the answers array (size 5) will have 'yess' + the '\0' (terminating zero). The second time around it looks like this:


    It seems like the rest of what I typed in i.e. carriage return, is inputed to fgets() without even asking for user input! Thats right! The second round fgets() skips user input entirely! (as you can see by the program stopping at the breakpoint in the pic, at the default clause of the switch statement)

    My conclusion is that the stdin buffer needs to be cleared from my understanding... Is there a way to do that?

    It is a character variable ;),

    Thanks for all the help guys! Fast response and friendly feedback is great! :eek:


    EDIT: I tried fflush(stdin) staright after fgets()... it didn't work...
    subsonix's, suggestion seems to match best the criteria stated in the code... Heh, I still would like to know how to make this universal if possible :). Thanks!
  6. macrumors 68040

    Feb 2, 2008
    What is commonly used in place of fflush(stdin), is a while loop like this:

    while( getchar() != '\n' );
  7. macrumors 6502

    Apr 29, 2010
    To quote Steve Martin, "Well, excuuuuuuuuuuuse meeeeeeeeee!" I should have said, "a scalar variable of type char." :D
  8. macrumors 68000

    Sep 8, 2006
    I remember when I had this NEW LINE problem I used a scanf after my fgets to absorb the new line left over. It may not be the best way but it worked for a small project I made when I was learning C

  9. thread starter macrumors newbie

    Apr 20, 2011
    OK, thanks for the replies guys... I'll go figure something out now that I have a couple of solutions :).


Share This Page