How do i clear the input buffer in C?

A place to discuss the implementation and style of computer programs.

Moderators: phlip, Moderators General, Prelates

Webbed_Toes
Posts: 67
Joined: Wed Feb 04, 2009 11:32 pm UTC
Location: New York
Contact:

How do i clear the input buffer in C?

Postby Webbed_Toes » Mon Jan 17, 2011 2:32 am UTC

I have a program
Spoiler:

Code: Select all

/*
Program Name: game
Author: Chris NeJame
Class: Introduction to Programming With C & MATLAB
Section: 4001-211-01
Program Intent: This is a simple game where the user must guess a
      randomly generated number between 1 and 100 in 4 guesses or less.
Input Data: One integer.
Output Data: Whether the number guessed is right or wrong and if it
      is wrong then whether ti is too high or too low.
*/

/*---------------
Include Section
----------------*/
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <math.h>
#include <time.h>
/*--------------------------- main function --------------------------------
Purpose:   This is a simple game where the user must guess a
      randomly generated number between 1 and 100 in 4 guesses or less.
Returns: 0
----------------------------------------------------------------------------*/

int game();

int main(void)
{
   char again;
   int empty;
   while(again == 'y'){
      char again;
      printf("Try to guess a number between 1 and 100"
         "\nYou have 4 guesses to find the number");
      game();
      printf("\nWould you like to play again?(y/n) ");
      scanf("%d%c", &empty, &again);
   }
   printf("\n***** Program Terminated *****\n");
   return (EXIT_SUCCESS);
}
int game()
{
   
   srand(time(NULL));
   int chances;
   chances = 1;
   int ran;
   ran = 1 + (rand() % 100);
   int guess;
   while(chances <= 4)
   {
      printf("\n?: ");
      scanf("%d", &guess);
      if(guess == ran)
      {
         printf("\nHooray! You win!");
         chances = 5;
      }
      else if(chances == 4)
      {
         printf("\nSorry you lose.");
         printf("\nThe number was %d", ran);
      }
      else
      {
         printf("\nWrong Number - Try Again");
         if(guess < ran)
         {
            printf("\nThe number you guessed is too small");
            printf("\nYou have %d guesses left", (4 - chances));
         }
         else
         {
            printf("\nThe number you guessed is too large");
            printf("\nYou have %d guesses left", (4 - chances));
         }
      }
      
      chances++;
   }
   return 0;
}

That asks you to guess a number between 1 and 100 within 4 guesses. I have that part down but when I run the code, after I win or lose and it asks me if I want to play again, no matter what I put in it freaks out and just starts going through it over and over again without waiting for my input for anything. I was told i might need to clear my input buffer but I don't know how to do that and a search didn't bring up anything. Any help would be appreciated
stephentyrone wrote:
Shriike wrote:good old fashion OOP

I just threw up a little bit in my mouth.

User avatar
MHD
Posts: 630
Joined: Fri Mar 20, 2009 8:21 pm UTC
Location: Denmark

Re: How do i clear the input buffer in C?

Postby MHD » Mon Jan 17, 2011 6:33 am UTC

Linky

In all fairness though, you should getchar() until it returns either '\n' or EOF and then wait for input.
EvanED wrote:be aware that when most people say "regular expression" they really mean "something that is almost, but not quite, entirely unlike a regular expression"

User avatar
You, sir, name?
Posts: 6983
Joined: Sun Apr 22, 2007 10:07 am UTC
Location: Chako Paul City
Contact:

Re: How do i clear the input buffer in C?

Postby You, sir, name? » Mon Jan 17, 2011 9:05 am UTC

MHD wrote:Linky

In all fairness though, you should getchar() until it returns either '\n' or EOF and then wait for input.


That makes some rather large assumptions about the nature of the buffering. Not to mention, if the buffer is empty, it freezes the program until someone presses return.
I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.

User avatar
Zabaron
Posts: 113
Joined: Wed Jun 04, 2008 3:33 am UTC
Location: Georgia

Re: How do i clear the input buffer in C?

Postby Zabaron » Mon Jan 17, 2011 10:47 pm UTC

Clearing the input buffer isn't what will make your code work. Adding your int empty to your scanf will not help. As it stands, scanf is reading all of the input, including the 'y'/'n' in its futile attempt to find an int in the user's input. Since scanf can't find what it's looking for, your program goes crazy. Instead of trying to get scanf to ignore the leading newline characters, you should just tell it they're going to be there. Change scanf's pattern to "\n%c" so that it knows there will be a newline character before the character you're looking for.

-Zabaron
I love deadlines. I love that wooshing sound they make as they fly by. -Douglas Adams

Token
Posts: 1481
Joined: Fri Dec 01, 2006 5:07 pm UTC
Location: London

Re: How do i clear the input buffer in C?

Postby Token » Tue Jan 18, 2011 2:27 am UTC

In my opinion at least, it is bad practice to read from stdin using scanf. scanf is best used when you have a reasonable assumption as to the format of your input. Unfortunately, user input can be pretty much anything. Even with Zabaron's suggestion, say, a user entering "1 2 3 4 5" will have your program quit immediately. Sure, they should have been more sensible, but this is not expected behaviour. There is one thing you can pretty much rely on, though - when you ask your program to get user input, it will wait until they hit the enter key to process it. So every time you get user input, you can expect an entire line - so you should *read* an entire line, and process it as a block before getting any more input, to minimize the level of unexpected behaviour in your program.

There are various solutions for doing this. The best is probably to use the getline function from the GNU C library. I'd also combine it with the string-to-long parsing strtol function from the same library, to get something like this:

Code: Select all

bool readIntFromStdin(int * outputInt)
{
  char * buffer = NULL;
  size_t sizeOfBuffer = 0;
  ssize_t numberOfCharactersRead;

  numberOfCharactersRead = getline(&buffer, &sizeOfBuffer, stdin);

  if (numberOfcharactersRead == -1)
  {
    free(buffer);
    return false;
  }

  long int integerRead;
  char * tail;

  integerRead = strtol(buffer, &tail, 10);
  free(buffer);

  if (tail == buffer) return false;

  *outputInt = (int) integerRead;

  return true;    
}

This will read an entire line from the standard input stream, and attempt to parse it as an int. It will work if the line consists of the following: any number of whitespace characters, followed by an optional + or -, followed by at least one digit 0-9, followed by any number of irrelevant garbage characters. If this is the case, it returns true and sets its argument appropriately. If not, it returns false. [I wrote this function without testing it, so don't assume it's bug free...]
All posts are works in progress. If I posted something within the last hour, chances are I'm still editing it.


Return to “Coding”

Who is online

Users browsing this forum: No registered users and 12 guests