Thread: Should be an easy C fix!

  1. #1
    Registered User
    Join Date
    Jul 2011
    Posts
    9

    Should be an easy C fix!

    Hello all,

    This is a homework problem, but I have written out the whole code already but am faced with a pretty stupid problem.. When I run the game in case 1, 2 or 3 and the game asks the player to play again, it simply skips over the scanf("%c", &cYesNo); and restarts the game without giving the user a chance to answer.. :\ Any help is greatly appreciated!

    Thanks!

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
    	char cYesNo = '\0';
    	int option = 0;
    	int game = 0;
    	int iResp1 = 0;
    	int iResp2 = 0;
    	int iResp3 = 0;
    	int iResp4 = 0;
    	int iResp5 = 0;
    	int iElaspedTime = 0;
    	int iCurrentTime = 0;
    	int iRandomNum = 0;
    	int i1 = 0;
    	int i2 = 0;
    	int i3 = 0;
    	int i4 = 0;
    	int i5 = 0;
    	int iCounter = 0;
    
    	srand(time(NULL));
    
    	system("cls");
    
    	printf("\n\t\tThank you for playing the concentration game!\n");
    
    	do
    	{
    		printf("\n\t1\tEasy - Remember 3 numbers in 5 seconds");
    		printf("\n\t2\tIntermediate - Remember 5 numbers in 5 seconds");
    		printf("\n\t3\tDifficult - Remember 5 numbers in 2 seconds");
    		printf("\n\t4\tQUIT");
    
    		printf("\n\n\tPlease choose difficulty (1 or 4): ");
    		scanf("%d", &option);
    
    		switch (option)
    		{
    			case 1:
    			{
    				i1 = rand() % 100;
    				i2 = rand() % 100;
    				i3 = rand() % 100;
    	
    				printf("\n\n\tConcentrate on the next three numbers\n");
    				printf("\n\t%d\t%d\t%d\n", i1, i2, i3);
    
    				iCurrentTime = time(NULL);
    
    				do
    				{
    					iElaspedTime = time(NULL);
    				} while( (iElaspedTime - iCurrentTime) < 5 ); //end do while loop
    
    				system("cls");
    
    				printf("\n\tEnter each # seperated with one space: ");
    				scanf("%d%d%d", &iResp1, &iResp2, &iResp3);
    
    				if( i1==iResp1 && i2==iResp2 && i3==iResp3 )
    					printf("\n\tCongratulations!\n\n");
    				else
    					printf("\n\tSorry, correct numbers were %d %d %d\n", i1, i2, i3);
    		
    				printf("\tPlay again (y or n)? ");
    				scanf("%c", &cYesNo);
    		
    				if( cYesNo == 'n' || cYesNo == 'N' )
    					game = 1;
    
    				break;
    			}
    
    			case 2:
    			{
    				i1 = rand() % 100;
    				i2 = rand() % 100;
    				i3 = rand() % 100;
    				i4 = rand() % 100;
    				i5 = rand() % 100;
    
    				printf("\n\n\tConcentrate on the next three numbers\n");
    				printf("\n\t%d\t%d\t%d\t%d\t%d\n", i1, i2, i3, i4, i5);
    
    				iCurrentTime = time(NULL);
    
    				do
    				{
    					iElaspedTime = time(NULL);
    				} while( (iElaspedTime - iCurrentTime) < 5 ); //end do while loop
    
    				system("cls");
    
    				printf("\n\tEnter each # seperated with one space: ");
    				scanf("%d%d%d%d%d", &iResp1, &iResp2, &iResp3, &iResp4, &iResp5);
    
    				if( i1==iResp1 && i2==iResp2 && i3==iResp3 && i4==iResp4 && i5==iResp5 )
    					printf("\n\tCongratulations!\n\n");
    				else
    					printf("\n\tSorry, correct numbers were %d %d %d %d %d\n", i1, i2, i3, i4, i5);
    
    				printf("\tPlay again (y or n)? ");
    				scanf("%c", &cYesNo);
    		
    				if( cYesNo == 'n' || cYesNo == 'N' )
    					game = 1;
    
    				break;
    			}
    
    			case 3:
    			{
    				i1 = rand() % 100;
    				i2 = rand() % 100;
    				i3 = rand() % 100;
    				i4 = rand() % 100;
    				i5 = rand() % 100;
    
    				printf("\n\n\tConcentrate on the next three numbers\n");
    				printf("\n\t%d\t%d\t%d\t%d\t%d\n", i1, i2, i3, i4, i5);
    
    				iCurrentTime = time(NULL);
    
    				do
    				{
    					iElaspedTime = time(NULL);
    				} while( (iElaspedTime - iCurrentTime) < 2 ); //end do while loop
    
    				system("cls");
    
    				printf("\n\tEnter each # seperated with one space: ");
    				scanf("%d%d%d%d%d", &iResp1, &iResp2, &iResp3, &iResp4, &iResp5);
    
    				if( i1==iResp1 && i2==iResp2 && i3==iResp3 && i4==iResp4 && i5==iResp5 )
    					printf("\n\tCongratulations!\n\n");
    				else	
    					printf("\n\tSorry, correct numbers were %d %d %d %d %d\n", i1, i2, i3, i4, i5);
    
    				printf("\tPlay again (y or n)? ");
    				scanf("%c", &cYesNo);
    		
    				if( cYesNo == 'n' || cYesNo == 'N' )
    					game = 1;
    
    				break;
    			}
    	
    			case 4:
    			{
    				printf("\n\t\tBye bye!\n");
    				game = 1;
    				break;
    			}
    		} // end switch
    		
    	} while (!game);
    	
    	return 0;
    
    } // end function

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Haakon
    When I run the game in case 1, 2 or 3 and the game asks the player to play again, it simply skips over the scanf("%c", &cYesNo); and restarts the game without giving the user a chance to answer.
    The problem is that the newline was left in the input buffer after the previous scanf read. Remove it by reading and discarding.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Jul 2011
    Posts
    9
    Thanks for the quick response laserlight, but honestly I have no idea what you just said.. haha

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You aren't just pressing one key. You are pressing one key + enter. But you are only reading one of the two, so the second gets left behind.


    Quzah.
    Hope is the first step on the road to disappointment.

  5. #5
    Registered User
    Join Date
    Jul 2011
    Posts
    9
    That makes sense.. So how do I fix it? Really these printf and scanf combinations is what I've done all along, just don't understand why this is happening now.

    Thanks

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    As I said, read and discard the newline before you read the character. This could be done by modifying the scanf format string, or using getchar(), etc.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    If you want a more in-depth explanation, check out this link.

    Follow through to question 12.20. At the bottom of that page, there's a link to a "longer explanation" if you want to know even more.

  8. #8
    Registered User
    Join Date
    May 2011
    Location
    Around 8.3 light-minutes from the Sun
    Posts
    1,949
    Code:
    printf("\n\n\tPlease choose difficulty (1 or 4): ");
    scanf("%d", &option);
    In the above code you take the player input however the newline character is left in the input buffer. Then the next time you call scanf() later in your code it is just reading in that character. Think of it like this:

    You ask the user for input.
    The user presses 1 then 'enter'.
    Your input buffer now has 1 | 'enter'
    You then call scanf() which reads one character from the input buffer so your input buffer looks like 'enter'|
    You then ask the user another question and he inputs 'y' then 'enter'
    Now the input buffer looks like: 'enter' | 'y' | 'enter'
    You then call scanf() which reads in the next character so now the input buffer looks like 'y' | 'enter'

    So as Laser informed you, you need to get rid of the extra character from the buffer. A simple way would be:

    Code:
    printf("\n\n\tPlease choose difficulty (1 or 4): ");
    scanf("%d", &option);
    getchar();
    Quote Originally Posted by anduril462 View Post
    Now, please, for the love of all things good and holy, think about what you're doing! Don't just run around willy-nilly, coding like a drunk two-year-old....
    Quote Originally Posted by quzah View Post
    ..... Just don't be surprised when I say you aren't using standard C anymore, and as such,are off in your own little universe that I will completely disregard.
    Warning: Some or all of my posted code may be non-standard and as such should not be used and in no case looked at.

  9. #9
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    This is one of the most common problems when you use scanf(), because scanf() always leaves the newline char ('\n'), behind in the input buffer.

    So the next scanf() for a single char, will surely fail. (That is, the scanf() will take the newline char, say "OK, I've got a char!", and the program moves on - looking like it "skipped" that line of code, entirely.

    The fix is to clean out the newline from the input buffer. The way, well one way is to add a getchar() after every scanf() -- problem solved.

    For scanf()'s for numbers it may not be a problem, but it can be a problem, even with numbers.

    Take this example:

    Code:
    #include <stdio.h>
    
    int main(void) {
      char ch;
      int choice;
    
      do {
        printf(\nSelect 1, 2, or 3 to quit: \n\n\t");
        printf("1. generate the report\n\n\t");
        printf("2. print the report\n\n\t");
        scanf("%d", &choice);
        //pulls the newline off the input buffer
        //ch = getchar();
          printf("\n\nYou entered %d\n", choice);
    
      }while(choice != 3);
    
      return 0;
    }
    Run the above, as is, and enter a 1 or 2 (whatever integer you like), and verify that it works OK. Now, instead of hitting a number, enter a single letter and watch it blow up! All because of the left over newline.

    Now compile and run it again, after removing the // from in front of the getchar() line of code. Again, enter a letter, instead of a number, and see what happens now.

    Note that the char ch, is never actually used for anything else except pulling the newline char off the input buffer.
    Last edited by Adak; 07-04-2011 at 08:50 PM.

  10. #10
    Registered User
    Join Date
    Jul 2011
    Posts
    9
    Wow, I'm a pretty big n008 when it comes to C and I would never have guessed this was the reason. So technically, could I not just replace my code with:

    Code:
    printf("\n\n\tPlease choose difficulty (1 or 4): ");
    option = getchar();
    Or would i still need the scanf?

  11. #11
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Try it and find out.


    Quzah.
    Hope is the first step on the road to disappointment.

  12. #12
    Registered User
    Join Date
    May 2011
    Location
    Around 8.3 light-minutes from the Sun
    Posts
    1,949
    Quote Originally Posted by Haakon View Post
    Wow, I'm a pretty big n008 when it comes to C and I would never have guessed this was the reason. So technically, could I not just replace my code with:
    Code:
    printf("\n\n\tPlease choose difficulty (1 or 4): ");
    option = getchar();
    Or would i still need the scanf?
    getchar() only takes one value off of the input buffer, just like scanf(). You would still have the same problem you are facing. For your implementation just stick with the scanf() and getchar() pairing as discussed above.
    Quote Originally Posted by anduril462 View Post
    Now, please, for the love of all things good and holy, think about what you're doing! Don't just run around willy-nilly, coding like a drunk two-year-old....
    Quote Originally Posted by quzah View Post
    ..... Just don't be surprised when I say you aren't using standard C anymore, and as such,are off in your own little universe that I will completely disregard.
    Warning: Some or all of my posted code may be non-standard and as such should not be used and in no case looked at.

  13. #13
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by AndrewHunter View Post
    getchar() only takes one value off of the input buffer, just like scanf(). You would still have the same problem you are facing. For your implementation just stick with the scanf() and getchar() pairing as discussed above.
    There's a reason I answered the way I did. Some times you just need to let people see for themselves. He's already had five different people tell him what was happening.


    Quzah.
    Hope is the first step on the road to disappointment.

  14. #14
    Registered User
    Join Date
    May 2011
    Location
    Around 8.3 light-minutes from the Sun
    Posts
    1,949
    @quzah - We must have been posting at the same time, I didn't see your response until after I posted. Not trying to step on your toes.
    Quote Originally Posted by anduril462 View Post
    Now, please, for the love of all things good and holy, think about what you're doing! Don't just run around willy-nilly, coding like a drunk two-year-old....
    Quote Originally Posted by quzah View Post
    ..... Just don't be surprised when I say you aren't using standard C anymore, and as such,are off in your own little universe that I will completely disregard.
    Warning: Some or all of my posted code may be non-standard and as such should not be used and in no case looked at.

  15. #15
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Quote Originally Posted by Haakon View Post
    Wow, I'm a pretty big n008 when it comes to C and I would never have guessed this was the reason. So technically, could I not just replace my code with:

    Or would i still need the scanf?
    Haakon, it's important to try these things out. Be a bit adventurous with your study of C. It's your world there, on your system - please go explore it.

    Andrew, I totally missed your post, since we were writing up replies at the same time. Didn't mean to repeat what you'd clearly posted.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Seg fault in easy, easy code
    By lisa1901 in forum C++ Programming
    Replies: 11
    Last Post: 12-10-2007, 05:28 AM
  2. Probably and easy one
    By confused0874 in forum C++ Programming
    Replies: 3
    Last Post: 06-08-2006, 06:03 AM
  3. Easy One!!
    By dug in forum C Programming
    Replies: 8
    Last Post: 12-12-2003, 03:43 AM
  4. Easy question, (should be) easy answer... ;-)
    By Unregistered in forum A Brief History of Cprogramming.com
    Replies: 1
    Last Post: 06-12-2002, 09:36 PM
  5. easy help
    By guss in forum C++ Programming
    Replies: 4
    Last Post: 12-18-2001, 02:33 PM