Register FAQ / Rules Forum Spy Search Today's Posts Mark Forums Read
Go Back   MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Reply
 
Thread Tools Search this Thread Display Modes
Old Apr 20, 2011, 07:25 PM   #1
confuded
macrumors newbie
 
Join Date: Apr 2011
[C] What happens to my char array?

Hi,

Please consider the following SHORT code:

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;
    do{
        printf("There are %d cups. One of them contains the ball.\n"
               "Which cup contains the ball?\n", kCups);
        
        //play again?
        bool validAnswer = false;
        do{
            printf("Play the game again?\n");
            char answer[4];
            fgets(answer, 4, stdin);
            switch(answer[0]){
                case 'y': case 'Y':
                    validAnswer = true;
                    break;
                case 'n': case 'N':
                    validAnswer = true;
                    exit = true;
                    break;
                default:
                    printf("Please enter a valid answer!\n");
            }
        }while(!validAnswer);
    }while(!exit);
    
    
    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!

~confuded

Last edited by confuded; Apr 21, 2011 at 01:49 PM. Reason: resolved
confuded is offline   0 Reply With Quote
Old Apr 20, 2011, 07:36 PM   #2
subsonix
macrumors 68030
 
Join Date: Feb 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].
subsonix is offline   0 Reply With Quote
Old Apr 21, 2011, 12:10 AM   #3
chown33
macrumors 603
 
Join Date: Aug 2009
Quote:
Originally Posted by subsonix View Post
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].
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.
chown33 is offline   0 Reply With Quote
Old Apr 21, 2011, 03:40 AM   #4
Bill McEnaney
macrumors 6502
 
Join Date: Apr 2010
Since you check only answer[0], to avoid the newline problem, why not declare answer as a character variable, not as a string?

Last edited by Bill McEnaney; Apr 21, 2011 at 03:58 AM.
Bill McEnaney is offline   0 Reply With Quote
Old Apr 21, 2011, 04:42 AM   #5
confuded
Thread Starter
macrumors newbie
 
Join Date: Apr 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?


Quote:
Originally Posted by Bill McEnaney View Post
Since you check only answer[0], to avoid the newline problem, why not declare answer as a character variable, not as a string?
It is a character variable ,


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

~confuded


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!

Last edited by confuded; Apr 21, 2011 at 04:58 AM. Reason: Adding things...
confuded is offline   0 Reply With Quote
Old Apr 21, 2011, 10:07 AM   #6
subsonix
macrumors 68030
 
Join Date: Feb 2008
Quote:
Originally Posted by confuded View Post
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!
What is commonly used in place of fflush(stdin), is a while loop like this:

Code:
while( getchar() != '\n' );
subsonix is offline   0 Reply With Quote
Old Apr 21, 2011, 10:29 AM   #7
Bill McEnaney
macrumors 6502
 
Join Date: Apr 2010
Quote:
Originally Posted by confuded View Post
It is a character variable
To quote Steve Martin, "Well, excuuuuuuuuuuuse meeeeeeeeee!" I should have said, "a scalar variable of type char."
Bill McEnaney is offline   0 Reply With Quote
Old Apr 21, 2011, 11:09 AM   #8
larswik
macrumors 65816
 
Join Date: Sep 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

-Lars
larswik is offline   0 Reply With Quote
Old Apr 21, 2011, 01:47 PM   #9
confuded
Thread Starter
macrumors newbie
 
Join Date: Apr 2011
OK, thanks for the replies guys... I'll go figure something out now that I have a couple of solutions .

~confuded
confuded is offline   0 Reply With Quote

Reply
MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Similar Threads
thread Thread Starter Forum Replies Last Post
OpenGL ES: #define BUFFER_OFFSET(i) ((char *)NULL + (i)) explanation Blakeasd iPhone/iPad Programming 4 Jul 4, 2013 05:38 PM
Array Containing Dictionaries ahan.tm iPhone/iPad Programming 2 Nov 18, 2012 10:31 AM
RAID Array help Lord Adama Mac Pro 3 Jun 5, 2012 10:27 PM

Forum Jump

All times are GMT -5. The time now is 12:43 PM.

Mac Rumors | Mac | iPhone | iPhone Game Reviews | iPhone Apps

Mobile Version | Fixed | Fluid | Fluid HD
Copyright 2002-2013, MacRumors.com, LLC