Thread: How to check if stdin needs to be flushed?

  1. #1
    Registered User
    Join Date
    Sep 2007
    Posts
    2

    How to check if stdin needs to be flushed?

    Hi Guys,


    I'm writing a client/server program as part of an operating systems class. I didn't realize how horrible I/O is in C until I started writing this program. I'm NOT using scanf() for obvious reasons, but fgets() is still giving me some trouble.

    Basically, I'm reading in 2 values with fgets() and I'm removing the \n character and replacing it with \0. But the problem is that if I write more input than fgets() is looking for, then I have a bunch of garbage still in the stdin buffer that ends up writing itself into my second variable. Here is (some of) my code:

    Code:
    printf("\n %s","Enter the ISBN Number of the Book: ");
    fgets(isbnNo,MAX_ISBN,stdin);
    for (i=0;i<MAX_ISBN;++i)
    {
       if (isbnNo[i] == '\n')
       isbnNo[i] = '\0';
    }
    
    printf("\n %s", "Enter the Book Title: ");
    fgets(bookTitle,MAX_STRING,stdin);
    for (i=0;i<MAX_STRING;++i)
    {
       if (bookTitle[i] == '\n')
       bookTitle[i] = '\0';
    }
    Only MAX_ISBN number of characters are being read into the string to prevent buffer overflow, but if I type more characters than MAX_ISBN it automatically inputs those extra characters into the next variable that is being input. The problem is easily solved using the following line of code:

    Code:
    while(getchar() != '\n') continue;
    However, if I didn't type more characters than MAX_ISBN then this will pause the system and wait for an extra newline character.

    Basically, I need a way to check if stdin needs to be flushed using the above line. Is there anyway to check if there is anything on the buffer (like a peek() function)? I tried using fflush(stdin) instead of the above line of code, but it doesn't work. Can anyone help?

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    In your check to see if there is a '\n' at the end of the string - if there isn't, then there's unread data in the input buffer.

    Code:
    while(getchar() != '\n') ;
    No need to use continue - it is just going to confuse people. You may want to do this tho:

    Code:
    int ch;
    ...
    while((ch = getchar()) != '\n' && ch != EOF) ;
    This will ensure that your program doesn't hang if:
    1. Someone happens to press the key that indicates EOF (Ctrl-D in a Unix or Linux system, CTRL-Z in a Windows, DOS or CP/M system).
    2. If your application is feed from a input file instead of from the console, and the file ends during the "flush input" phase.

    As you have discovered, fflush(stdin) doesn't do anything useful - it is technically "undefined", so it can do just about anything (including crashing the system), but it's most likely just not doing anything. See the FAQ for more info on the subject.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    If you always read into a large temporary buffer first, then validate the input before assigning it to the correct storage, the 'flush' problem pretty much goes away.

    char buff[BUFSIZ];
    fgets( buff, sizeof buff, stdin );
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Salem View Post
    If you always read into a large temporary buffer first, then validate the input before assigning it to the correct storage, the 'flush' problem pretty much goes away.

    char buff[BUFSIZ];
    fgets( buff, sizeof buff, stdin );
    Yes, that's a better way, really.

    The other alternative, which is better in some way, but much more complicated in other ways, is to actually do all the management of the input yourself. This is more complicated because you'd have to deal with handling backspace/delete and such, as well as the fact that setting up the input so that it works in "raw" mode is specific to the OS the system is running on. Not something a beginner should be doing.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Registered User
    Join Date
    Sep 2007
    Posts
    2
    Wow, two very good solutions. I don't know why I didn't think of either of them.

    Problem solved. I now know how to write secure input in C! Thanks to both of you!!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. BN_CLICKED, change button style
    By bennyandthejets in forum Windows Programming
    Replies: 13
    Last Post: 07-05-2010, 11:42 PM
  2. Checking stdin for input
    By hawaiian robots in forum C Programming
    Replies: 7
    Last Post: 05-19-2009, 09:06 AM
  3. Another syntax error
    By caldeira in forum C Programming
    Replies: 31
    Last Post: 09-05-2008, 01:01 AM
  4. value of stdin (not zero?)
    By taisao in forum Linux Programming
    Replies: 3
    Last Post: 05-27-2007, 08:14 AM
  5. large program code ,please help
    By Ash1981 in forum C Programming
    Replies: 14
    Last Post: 01-30-2006, 06:16 AM