Thread: flushall()

  1. #1
    Registered User
    Join Date
    Dec 2007
    Posts
    84

    flushall()

    Hi All,

    The FAQ say to not use:
    Code:
    flushall();
    Because of an unexpected behavior.
    I still don't understand how can I run the following code without this command

    Code:
    int main(void)
    {
      int a;
      char buf[20];
    
      puts("Put a number:");
      scanf("%d",&a);
      fgets(buf,20,stdin);
      return 0;
    }
    Thank you

  2. #2
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Quote Originally Posted by salvadoravi View Post
    I still don't understand how can I run the following code without this command
    Don't press enter after the number, use just a space( actually not even the space is needed if your string doesn't start with a number).
    Kurt

  3. #3
    Registered User
    Join Date
    Dec 2007
    Posts
    84

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Well, what's wrong with it?

    If you're worried about making sure that the prompt gets out there before the input gets read in, you can fflush(stdout) before the scanf. Most compilers know that stdin and stdout are interactive, so that everything gets done properly; but if you don't trust them, you can force the issue.

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Why do you believe that flushall() will be at all useful in this instance?

    In particular since puts() appends a newline to the output, which, in nearly all C runtime implementations implies a flush.

    --
    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.

  6. #6
    Registered User
    Join Date
    Dec 2007
    Posts
    84
    Quote Originally Posted by matsp View Post
    Why do you believe that flushall() will be at all useful in this instance?

    In particular since puts() appends a newline to the output, which, in nearly all C runtime implementations implies a flush.

    --
    Mats
    The following code always worked for me:
    Code:
    int main(void)
    {
      int a;
      char buf[20];
    
      puts("Put a number:");
      scanf("%d",&a);
      flushall();
      fgets(buf,20,stdin);
      return 0;
    }
    Here was the first time I read not to use it and clear the buffer in other ways:
    the problem is that the solution offered in the FAQ can cause undesirable results too:
    Quote from FAQ
    "If you call these when there is no data in the input stream, the program will wait until there is, which gives you undesirable results."

    I really don't know which one is worst, using flushall(Witch always worked for me) or the one suggested in the FAQ.
    Both can give undesirable results!
    There must be something I can do to run the code above properly!

    Thank you again
    Last edited by salvadoravi; 12-21-2007 at 08:12 AM.

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Well, it's really a question of "don't mix line input and other input functions, unless you are prepared to deal with the consequences". To put that a different way: Choose either scanf() or fgets(). You can always use a mix of fgets() and sscanf().

    fflush(stdin) is definitely bad - it is UNDEFINED. Imagine a small embedded system where memory is tight. To conserve memory, an input only file is shortened, because it doesn't need the output buffer that the output files have [and this is the BIG part of the structure behind a FILE pointer]. When you call fflush() on an input only file, it will attempt to access the data in the output section of the data structure - which isn't there. The consequence of this may be that the system crashes, or that some random data is output to some random file/console location. Not a particularly good thing.

    The function "flushall()" is just a loop doing "fflush()" on every file in the system, which of course means that stdin will be flushed, along with any other input and output files that are currently open. Not a particularly good idea.

    --
    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.

  8. #8
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Quote Originally Posted by salvadoravi View Post
    There must be something I can do to run the code above properly!
    Yes shure. Never mix scanf with fgets.
    Read all your input with fgets. If you have to extract numbers from the input use sscanf instead.
    Kurt

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by salvadoravi View Post
    The following code always worked for me:
    And you have tried this on how many different compilers, OS's and processor types [I'm not talking about AMD & Intel processors - they are ONE type]?


    When something is undefined, it doesn't (necessarily) mean that it's not going to work - it just means that it's ALWAYS going to work.

    --
    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.

  10. #10
    Registered User
    Join Date
    Sep 2006
    Posts
    230
    why is flushall() included in the standard library if it has undefined behavior?

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Abda92 View Post
    why is flushall() included in the standard library if it has undefined behavior?
    It is not in the strict ANSI standard. It is a common extension [and it may even WORK for most cases].

    http://www-ccs.ucsd.edu/c/

    Look up stdio.h: no flushall in the list of functions.

    --
    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.

  12. #12
    Registered User ssharish2005's Avatar
    Join Date
    Sep 2005
    Location
    Cambridge, UK
    Posts
    1,732
    Quote Originally Posted by Abda92 View Post
    why is flushall() included in the standard library if it has undefined behavior?
    I dont even have fflushall() on my compiler

    Code:
      [Linker error] undefined reference to `fflushall'
    ssharish

  13. #13
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by ssharish2005 View Post
    I dont even have fflushall() on my compiler

    Code:
      [Linker error] undefined reference to `fflushall'
    ssharish
    Even spelled with one f?

    But yes, it's not standard.

    One would expect that the function would safe-ish - but to assume that fflush() on an input actually does what the above code expects is a different story.

    And assuming that it does, why would anyone think that it's better to call flushall() than [not that I'm recommending this solution either] fflush(stdin)? The only difference is that flushall() _ALSO_ flushes any other files that may be open at this time - what's the benefit of that? Note that flushing a file _HAS_ side-effects on that file - so unless you know exactly all the files are open and in what state they are, you are "messing with things you don't have a right to mess with".

    Also to the original poster about "how do I know I can call the clear input buffer code?" - if you have successfully come back from a scanf() call, then you DO know that there is at least a neline character ('\n') somewhere waiting to be read. Whether there is also "other stuff" in there is a different question. But there will certainly be a newline - there is no doubt about that. That is because scanf will not receive any of the data from the console/input file before a newline is encountered [1]. This is guaranteed by the way that stdio functions work in C [2].


    [1] With one exception - if an end-of-file is reached before a newline is seen, then the input buffer is also released to the input function - so make sure you check for end-of-file when clearing the input buffer.

    [2] In some systems YOU CAN change the behaviour of the console input buffering - but this is special functions that you wouldn't use in normal programming. Of the many, many programs I've written so far, maybe 1-2% of them have used this, and I'm sure there are programmers who have worked 20 years without EVER using this sort of modified behaviour of IO - and you can't [in a reliable way] use scanf() or fgets() in this mode of operation.

    --
    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.

  14. #14
    Registered User
    Join Date
    Dec 2007
    Posts
    84
    Quote Originally Posted by matsp View Post
    Well, it's really a question of "don't mix line input and other input functions, unless you are prepared to deal with the consequences". To put that a different way: Choose either scanf() or fgets(). You can always use a mix of fgets() and sscanf().
    I started to implement the code as follows:
    Code:
    int main(void)
    {
      char cNum[10];
      int iNum=0;
      char cStr[20];
     
      puts("Enter a number:");
      fgets(cNum,10,stdin);
      sscanf(cNum,"%d",&iNum);
      puts("Enter a string:");
      fgets(cStr,20,stdin);
      
      printf("Num=%d\n",iNum);
      puts(cStr);
      return 0;
    }
    It seems to be working fine until a longgggg numbers is enter.
    What am I doing wrong.

    Thank you

  15. #15
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Integers have finite capacity - about 2 billion on a 32/64-bit system, 32000 and a bit on a 16-bit compiler.

    If you want to deal with larger numbers than that, you need to use a different type than int - what is the right solution depends on what you actually are trying to do.

    --
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 19
    Last Post: 04-04-2009, 08:37 AM
  2. flushall() in DEVC++
    By vddking2 in forum C++ Programming
    Replies: 1
    Last Post: 11-21-2006, 09:26 PM
  3. clearing invalid value from memory
    By StringQuartet13 in forum C++ Programming
    Replies: 3
    Last Post: 09-29-2003, 09:19 PM
  4. Serial Communications with win32 api
    By Blackthorne in forum C Programming
    Replies: 1
    Last Post: 01-26-2003, 12:45 PM
  5. what is flushall() ?
    By drharv in forum C Programming
    Replies: 3
    Last Post: 02-18-2002, 10:13 PM