Thread: Life without fflush(stdin)

  1. #1
    Registered User
    Join Date
    Sep 2013
    Posts
    82

    Life without fflush(stdin)

    Hey guys,
    I have been using fflush(stdin) since I started programming, when I came across this site, I found out fflush(stdin) is wrong to use. When I don't use fflush(stdin), the program sometimes doesn't even wait for user to input some text, eg:
    Code:
    printf("Title: ");
    fgets (cds[count].title,200,stdin);
           
    printf("Artist: ");
    fgets (cds[count].artist,200,stdin);
    When the code is executed it doesn't waits for the user to input title;
    Title: Artist:
    Especially when something is in a loop it will ask for user input the first time, then the second time it wouldn't ask for input, third time it will ask again. So is there any other solution to this?

    P.S: I am using Dev-cpp, in case if the IDE matters.
    Last edited by Harith; 09-16-2013 at 01:18 AM.

  2. #2
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    one way to solve it - to use fgets for all your inputs

    another - use FAQ > Flush the input buffer - Cprogramming.com
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  3. #3
    Registered User
    Join Date
    Sep 2013
    Posts
    82
    Quote Originally Posted by vart View Post
    one way to solve it - to use fgets for all your inputs
    I am using fgets, but for integer I have to use scanf.

  4. #4
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    Although no technique is perfect, have a look at the line with the "while" loop on vart's link
    Fact - Beethoven wrote his first symphony in C

  5. #5
    Stoned Witch Barney McGrew's Avatar
    Join Date
    Oct 2012
    Location
    astaylea
    Posts
    420
    Have you considered just designing an protocol for your program, then just go through and read the data you need? It's far more straightforward than writing interactive programs that try to synchronise stdin and stdout. The plus side of this is you can use stdout for useful information instead of annoying prompts, and your protocol will work not only with terminals, but files and pipes too.

  6. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by Harith View Post
    I am using fgets, but for integer I have to use scanf.
    It's not necessary to use scanf(). In fact, it is a really bad idea to mix calls of scanf() or fscanf() with calls of fgets() on the same stream.

    Read the input using fgets() and parse the string obtained for an integer (int, long, or whatever type you seek) using sscanf(). atoi() is an alternative to sscanf() - assuming you are reading to a variable of type int.

    Using fgets() to read and then parsing the input is actually more flexible than using scanf() or similar functions to read directly from a stream.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  7. #7
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    vart and grumpy have the right of it. I actually prefer strtol/strtod instead of atoi for parsing out long or double data from a string. They're like atoi, but they have more features and better error handling.

  8. #8
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    It should be noted that it might still be necessary to flush the input when using "fgets()" with stdin.

    Consider these two examples:

    Code:
    /* example 1 - User input less than array size - newline gets stored */
     
    char userString[10];
     
    fgets(userString,10,stdin);
     
    /* user enters "Hello\n" */
     
    userString[0] = 'H'
    userString[1] = 'e'
    userString[2] = 'l'
    userString[3] = 'l'
    userString[4] = 'o'
    userString[5] = '\n'
    userString[6] = '\0'
    
    /* it's usually desired to have additional code that removes the newline from the array */
    Code:
    /* example 2 - User input greater than array size */
    /* Protected from overflow, but newline does not get stored */
     
    char userString[5];
     
    fgets(userString,5,stdin);
     
    /* user enters "Goodbye\n" */
     
    userString[0] = 'G'
    userString[1] = 'o'
    userString[2] = 'o'
    userString[3] = 'd'
    userString[4] = '\0'
     
    /* no newline in array - this means 'b', 'y', 'e', and '\n' are still */
    /* waiting on the buffer and need to be removed */
    I usually approach user input like this:

    - Read from stdin with "fgets()"
    - If there's a newline in the string, replace it with a null character
    - Else, flush the input buffer (such as with the example provided in the link by vart in post #2)
    - Process/validate data
    - etc...

    It's obviously best to have this sort of code in its own function. As an exercise, you can create separate functions for reading strings, reading integers, etc, using the advice given by grumpy and anduril462.

  9. #9
    Registered User
    Join Date
    Mar 2012
    Location
    the c - side
    Posts
    373
    I would also use fflush(stdout) after both printf, since there are no terminating newline characters.
    Last edited by gemera; 09-16-2013 at 11:08 AM. Reason: spelling

  10. #10
    Registered User
    Join Date
    Sep 2013
    Posts
    82
    One more thing, the code given in the FAQ:http://faq.cprogramming.com/cgi-bin/...&id=1043284392, do I have to use it after every input?
    Last edited by Harith; 09-16-2013 at 11:28 PM.

  11. #11
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    No, you don't have to use it after every input; in fact it might be easier to design input routines that don't skip input. If you can read a big enough string something like flushing is not a problem. You can even write up something that dynamically allocates a string big enough.

  12. #12
    Registered User
    Join Date
    Sep 2013
    Posts
    2
    using fflush(stdin) is not wrong...
    it actually clears the input stream of any unintended characters, like when you use a loop to take a string input character by character, first time you press a key and that is saved into the input stream and thereby at the variable, next when you press enter '\n' is inputted into the input stream thus automatically saving it into the variable location...thereby actually skipping to ask for user input.
    IDE does not matter

  13. #13
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by Shatroopa View Post
    using fflush(stdin) is not wrong...
    Yes it is. Because the C standard states fflush() has undefined behaviour on an input stream.

    If you want predictable or defined behaviour (i.e. behaviour you can rely on with all C compilers and libraries) then using fflush(stdin) is a wrong choice.

    Quote Originally Posted by Shatroopa View Post
    it actually clears the input stream of any unintended characters, like when you use a loop to take a string input character by character, first time you press a key and that is saved into the input stream and thereby at the variable, next when you press enter '\n' is inputted into the input stream thus automatically saving it into the variable location...thereby actually skipping to ask for user input.
    IDE does not matter
    Not true. It is true that fflush(stdin) behaves like you describe with a small number of compilers and libraries. However, since the standard says it has undefined behaviour on input streams, such behaviour is not required. And, in practice, fflush(stdin) does NOT give the behaviour you describe with most real-world compilers.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Newbie Question - fflush(stdin) & fpurge(stdin) on Mac and PC
    By tvsinesperanto in forum C Programming
    Replies: 34
    Last Post: 03-11-2006, 12:13 PM
  2. fflush(stdin)
    By kewell in forum C Programming
    Replies: 3
    Last Post: 07-20-2002, 04:27 PM
  3. fflush(stdin)
    By RyeDunn in forum C Programming
    Replies: 24
    Last Post: 07-18-2002, 09:07 PM
  4. ascii 10 in the stdin after fflush(stdin)??
    By Kev2 in forum A Brief History of Cprogramming.com
    Replies: 3
    Last Post: 06-03-2002, 03:53 PM
  5. fflush(stdin)
    By Unregistered in forum C Programming
    Replies: 14
    Last Post: 04-21-2002, 01:19 AM

Tags for this Thread