alternative for fflush(stdin)

This is a discussion on alternative for fflush(stdin) within the C Programming forums, part of the General Programming Boards category; To my horror, i just realised fflush(stdin) is suppose to have undefined behaviour. Can someone tell a proper alternative to ...

  1. #1
    Registered User
    Join Date
    Sep 2003
    Posts
    133

    alternative for fflush(stdin)

    To my horror, i just realised fflush(stdin) is suppose to have undefined behaviour. Can someone tell a proper alternative to remove unwanted characters in the input stream?

  2. #2
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,796
    One way:
    Code:
    int c;
    while ( ( c = getchar() ) != EOF && c != '\n' )
      ;
    Another way:
    Code:
    scanf ( "%*[^\n]" );
    scanf ( "%*c" );
    Another variation:
    Code:
    scanf ( "%*[^\n]" );
    getchar();
    Of course, if you find yourself doing this a lot you should wonder why your input constructs aren't being used more elegantly.
    My best code is written with the delete key.

  3. #3
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,659
    Code:
    int ch;
    while ( (ch=getchar()) != EOF && ch != '\n' ) { /* nothing */ }
    
    or more tersely
    while ( (ch=getchar()) != EOF && ch != '\n' );
    The problem pretty much goes away once you stop using scanf() for reading input and always use fgets(). fgets() is far more predictable about how much data it will read from a stream.

    So
    Code:
    int myint;
    scanf("%d",&myint);
    // some hacky flush
    Would become
    Code:
    int myint;
    char buff[BUFSIZ];
    fgets( buff, sizeof buff, stdin );
    sscanf( buff, "%d", &myint );
    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.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  4. #4
    Registered User
    Join Date
    Sep 2003
    Posts
    133
    Code:
    int c;
    while ( ( c = getchar() ) != EOF && c != '\n' );
    sorry, but i dont understand why do u need to compare the character with '\n' and eof. why not just eof? since basically, u want to flush everything in the stream?

    And what this mean?

    Code:
    scanf ( "%*[^\n]" );
    i understand %[^\n] is used to match anything except the newline, but what is * for?

  5. #5
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,796
    >since basically, u want to flush everything in the stream?
    When a program asks you for input, do you use the enter key or the EOF control combination to end your input? Chances are you've done both, so we test for both so that a loop doesn't get hung waiting for EOF when your input was terminated with a newline.

    >but what is * for?
    It means throw away whatever is read. You don't need it since it's supposedly garbage, so why assign it to valuable memory?
    My best code is written with the delete key.

  6. #6
    c99
    c99 is offline
    Registered User
    Join Date
    Feb 2004
    Posts
    79
    Prelude.

    Is there a chance of catching Ctrl+Z or F6 (EOF) using a signal handler?

    signal(?, func);
    R.I.P C89

  7. #7
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    Originally posted by c99
    Prelude.

    Is there a chance of catching Ctrl+Z or F6 (EOF) using a signal handler?

    signal(?, func);
    I don't believe there is, EOF is passed to the application via a read call of some sort (fgets etc).

    Out of interest, to see what signals are being sent by what action, you can always try something like this to trap every signal and go from there:
    Code:
    #include <stdio.h>
    #include <signal.h>
    
    void handler(int sig)
    {
      printf ("Got signal %d\n", sig);
    }
    
    int main(void)
    {
      int i;
      char buf[BUFSIZ];
      
      for (i = 0; i < NSIG; i++)
      {
        signal(i, handler);
      }
      
      fgets(buf, sizeof(buf), stdin);
      
      return(0);
    }
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  8. #8
    c99
    c99 is offline
    Registered User
    Join Date
    Feb 2004
    Posts
    79
    Hammer.

    Thanks, seems I can only manage to raise one signal from kbd action, SIGINT (Ctrl+C).
    R.I.P C89

  9. #9
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,006
    Originally posted by Hammer
    Out of interest, to see what signals are being sent by what action, you can always try something like this to trap every signal and go from there:
    Code:
    #include <stdio.h>
    #include <signal.h>
    
    void handler(int sig)
    {
      printf ("Got signal %d\n", sig);
    }
    
    int main(void)
    {
      int i;
      char buf[BUFSIZ];
      
      for (i = 0; i < NSIG; i++)
      {
        signal(i, handler);
      }
      
      fgets(buf, sizeof(buf), stdin);
      
      return(0);
    }
    I don't believe it is correct to call printf (or most other standard library functions) in a signal handler that is invoked asynchronously.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  10. #10
    Registered User
    Join Date
    Sep 2003
    Posts
    133
    Ok, now i understand how to flush properly. Thanks guys.

  11. #11
    Registered User
    Join Date
    Apr 2011
    Posts
    62
    Code:
    int c;
    while ( ( c = getchar() ) != EOF && c != '\n' );
    sorry for the, most likely, dumb question but is there any particular reason to use an int and not a char there?

  12. #12
    Registered User
    Join Date
    Jun 2005
    Posts
    6,425
    Quote Originally Posted by killme View Post
    sorry for the, most likely, dumb question but is there any particular reason to use an int and not a char there?
    Because getchar() returns an int value, and because EOF may be (in fact, usually is in practice) a value that can be represented correctly using an int but not using a char.
    Right 98% of the time, and don't care about the other 3%.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. ASP.NET alternative to gallery.menalto.com ???
    By gicio in forum C# Programming
    Replies: 0
    Last Post: 05-15-2005, 11:31 AM
  2. square root alternative
    By FH|RogueHunter in forum C++ Programming
    Replies: 1
    Last Post: 03-28-2005, 09:17 PM
  3. Alternative win32 compiler? And linking asm libs?
    By JMB in forum C++ Programming
    Replies: 4
    Last Post: 10-11-2002, 01:22 PM
  4. Alternative to fstream
    By golfinguy4 in forum Windows Programming
    Replies: 3
    Last Post: 07-03-2002, 01:51 AM
  5. alternative o/s programming
    By iain in forum A Brief History of Cprogramming.com
    Replies: 12
    Last Post: 01-19-2002, 08:14 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21