scanf behaviour

Discussion in 'C Programming' started by stasgold@gmail.com, Nov 24, 2006.

  1. Guest

    Hello.

    I maybe reinvent the weel ...
    I'm trying to read positive integer number with the help of scanf, if
    the input value is not positive number but negaive one zero or char , i
    have to reread the input until I get the needed pos. number

    I wrote the code , but it doesn't work the way it should : if i put
    some char into input, the program goes infinite loop instead of
    promting me to enter a new value.

    Please shed some light on what is the problem. thanks
    Code:
    #include <stdio.h>
    
    int main()
    {
    	int n;
    	while (1)
    	{
    		printf("Please enter positive number \n");
    		if ( scanf("%d",&n)!=1 || n<=0 )
    		{
    			printf("Illegal input!\n");
    			continue; 
    		}
    		
    	return 0;
    	}
    return 1;
    }
    
     
    , Nov 24, 2006
    #1
    1. Advertising

  2. Ian Collins Guest

    wrote:
    > Hello.
    >
    > I maybe reinvent the weel ...
    > I'm trying to read positive integer number with the help of scanf, if
    > the input value is not positive number but negaive one zero or char , i
    > have to reread the input until I get the needed pos. number
    >
    > I wrote the code , but it doesn't work the way it should : if i put
    > some char into input, the program goes infinite loop instead of
    > promting me to enter a new value.
    >

    That's because the conversion fails and the characters remain in the
    stream. So the next time scanf is called, the same character sequence is
    read.

    Add

    fflush( stdin );

    after your printf.

    > Please shed some light on what is the problem. thanks
    >
    Code:
    > #include <stdio.h>
    > 
    > int main()
    > {
    > 	int n;
    > 	while (1)
    > 	{
    > 		printf("Please enter positive number \n");
    > 		if ( scanf("%d",&n)!=1 || n<=0 )
    > 		{
    > 			printf("Illegal input!\n");
    > 			continue; 
    > 		}
    > 		
    > 	return 0;
    > 	}
    > return 1;
    > }
    > 
    >



    --
    Ian Collins.
     
    Ian Collins, Nov 24, 2006
    #2
    1. Advertising

  3. Ian Collins said:

    > Add
    >
    > fflush( stdin );


    No, don't do that. The behaviour of fflush on streams open for input is
    undefined.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at the above domain, - www.
     
    Richard Heathfield, Nov 24, 2006
    #3
  4. Ian Collins Guest

    Richard Heathfield wrote:
    > Ian Collins said:
    >
    >
    >>Add
    >>
    >>fflush( stdin );

    >
    >
    > No, don't do that. The behaviour of fflush on streams open for input is
    > undefined.
    >

    Oops, so it is.

    I've always used the Solaris man page definition:

    "If stream points to an input stream or an update stream into
    which the most recent operation was input, that stream is
    flushed if it is seekable and is not already at end-of-file."

    --
    Ian Collins.
     
    Ian Collins, Nov 24, 2006
    #4
  5. wrote:
    > I maybe reinvent the weel ...


    No, you just found out that scanf() is not very well suited for
    dealing with user input. You're definitely not the first and
    won't be the last;-)

    > I'm trying to read positive integer number with the help of scanf, if
    > the input value is not positive number but negaive one zero or char , i
    > have to reread the input until I get the needed pos. number


    > I wrote the code , but it doesn't work the way it should : if i put
    > some char into input, the program goes infinite loop instead of
    > promting me to enter a new value.


    > Please shed some light on what is the problem. thanks


    > #include <stdio.h>


    > int main()


    int main( void )

    tends to be better since your main() function doesn't take any input.

    > {
    > int n;
    > while (1)
    > {
    > printf("Please enter positive number \n");
    > if ( scanf("%d",&n)!=1 || n<=0 )


    The problem you're facing is that when scanf() doesn't find what
    it's looking for it won't read anything at all. So if the user inputs
    something that doesn't start with a number (with optionally a '+' or
    '-' in front of it) it stops immediately and nothing of the users
    input gets consumed. When scanf() then tries to read again it still
    finds the same characters it couldn't deal with already the last time
    and bails out again. Repeat at nauseam...

    In this case there are two ways t deal with it. The probably saner
    approach is to use a function like fgets() to read the input as a
    string, analyze this string for a number you are prepared to accept,
    and then to use e.g. strtol() to get at that number (which also allows
    to do full error checking).

    But since you're here just looking for a positive integer there's
    the following alternative:

    #include <stdio.h>

    int main( void )
    {
    char buffer[10];
    int x ;

    do {
    printf( "Please enter positive number\n" );
    while ( scanf( "%9[^-+0-9]", buffer ) != 0 )
    /* empty */ ;
    } while ( scanf( "%d", &x ) != 1 || x <= 0 );
    printf( "Got %d", x );
    return 0;
    }

    The scanf() in the while loop consumes all non-numerical input
    (except '+' and '-') and then the scanf() in the do loops
    condition tries to read in an integer. If that works and the
    number is positive the loop ends. If not we're back to square
    one. But there's still the problem that you can't check if the
    user input a number that's too large to be stored in an integer.
    Such checks can only be done using the approach mentioned first.
    And, of course, it also will return 123 for e.g. "asa%#123.12"
    (and leaves everything following the "123" in the input buffer)
    - I don't know if that's what you want.

    Regards, Jens
    --
    \ Jens Thoms Toerring ___
    \__________________________ http://toerring.de
     
    Jens Thoms Toerring, Nov 25, 2006
    #5
  6. CBFalconer Guest

    Jens Thoms Toerring wrote:
    > wrote:
    >
    >> I maybe reinvent the weel ...

    >
    > No, you just found out that scanf() is not very well suited for
    > dealing with user input. You're definitely not the first and
    > won't be the last;-)
    >
    >> I'm trying to read positive integer number with the help of scanf,
    >> if the input value is not positive number but negaive one zero or
    >> char , i have to reread the input until I get the needed pos. number

    >
    >> I wrote the code , but it doesn't work the way it should : if i put
    >> some char into input, the program goes infinite loop instead of
    >> promting me to enter a new value.

    >

    .... snip code using scanf ...
    >
    > The scanf() in the while loop consumes all non-numerical input
    > (except '+' and '-') and then the scanf() in the do loops
    > condition tries to read in an integer. If that works and the
    > number is positive the loop ends. If not we're back to square
    > one. But there's still the problem that you can't check if the
    > user input a number that's too large to be stored in an integer.
    > Such checks can only be done using the approach mentioned first.
    > And, of course, it also will return 123 for e.g. "asa%#123.12"
    > (and leaves everything following the "123" in the input buffer)
    > - I don't know if that's what you want.


    ONLY be done? See the following. No buffers needed. Improved
    since the published version. I am not completely happy with the
    treatment of negative values in readxint. Also it needs to be
    revised to use longs as the fundamental input mechanism. Note the
    GPL licence.

    /* ------------------------------------------------- *
    * File txtinput.c *
    * ------------------------------------------------- */

    #include <limits.h> /* xxxx_MAX, xxxx_MIN */
    #include <ctype.h> /* isdigit, isblank, isspace */
    #include <stdio.h> /* FILE, getc, ungetc */
    #include "txtinput.h"

    /* For licensing restrictions (GPL) see readme.txt in:
    * <http://cbfalconer.home.att.net/download/txtio.zip>
    *
    * These stream input routines are written so that simple
    * conditionals can be used:
    *
    * if (readxint(&myint, stdin)) {
    * do_error_recovery; normally_abort_to_somewhere;
    * }
    * else {
    * do_normal_things; usually_much_longer_than_bad_case;
    * }
    *
    * They allow overflow detection, and permit other routines to
    * detect the character that terminated a numerical field. No
    * string storage is required, thus there is no limitation on
    * the length of input fields. For example, a number entered
    * with a string of 1000 leading zeroes will not annoy these.
    *
    * The numerical input routines *NEVER* absorb a terminating
    * char (including '\n'). Thus a sequence such as:
    *
    * err = readxint(&myint, stdin);
    * flushln(stdin);
    *
    * will always consume complete lines, and after execution of
    * readxint a further getc (or fgetc) will return the character
    * that terminated the numeric field.
    *
    * They are also re-entrant, subject to the limitations of file
    * systems. e.g interrupting readxint(v, stdin) operation with
    * a call to readxwd(wd, stdin) would not be well defined, if
    * the same stdin is being used for both calls. If ungetc is
    * interruptible the run-time system is broken.
    *
    * Originally issued 2002-10-07
    *
    * Revised 2006-01-15 so that unsigned entry overflow (readxwd)
    uses the normal C modulo (UINT_MAX + 1) operation. readxwd
    still rejects an initial sign as an error.
    */

    /* -------------------------------------------------------------
    * Skip to non-blank on f, and return that char. or EOF The next
    * char that getc(f) will return is unknown. Local use only.
    */
    static int ignoreblks(FILE *f)
    {
    int ch;

    do {
    ch = getc(f);
    } while ((' ' == ch) || ('\t' == ch));
    /* while (isblank(ch)); */ /* for C99 */
    return ch;
    } /* ignoreblks */

    /*--------------------------------------------------------------
    * Skip all blanks on f. At completion getc(f) will return
    * a non-blank character, which may be \n or EOF
    *
    * Skipblks returns the char that getc will next return, or EOF.
    */
    int skipblks(FILE *f)
    {
    return ungetc(ignoreblks(f), f);
    } /* skipblks */

    /*--------------------------------------------------------------
    * Skip all whitespace on f, including \n, \f, \v, \r. At
    * completion getc(f) will return a non-blank character, which
    * may be EOF
    *
    * Skipwhite returns the char that getc will next return, or EOF.
    */
    int skipwhite(FILE *f)
    {
    int ch;

    do {
    ch = getc(f);
    } while (isspace(ch));
    return ungetc(ch, f);
    } /* skipwhite */

    /*--------------------------------------------------------------
    * Read an unsigned value. Signal error for overflow or no
    * valid number found. Returns 1 for error, 0 for noerror, EOF
    * for EOF encountered before parsing a value.
    *
    * Skip all leading blanks on f. At completion getc(f) will
    * return the character terminating the number, which may be \n
    * or EOF among others. Barring EOF it will NOT be a digit. The
    * combination of error, 0 result, and the next getc returning
    * \n indicates that no numerical value was found on the line.
    *
    * If the user wants to skip all leading white space including
    * \n, \f, \v, \r, he should first call "skipwhite(f);"
    *
    * Peculiarity: This specifically forbids a leading '+' or '-'.
    */
    int readxwd(unsigned int *wd, FILE *f)
    {
    unsigned int value, digit;
    int status;
    int ch;

    #define UWARNLVL (UINT_MAX / 10U)
    #define UWARNDIG (UINT_MAX - UWARNLVL * 10U)

    value = 0; /* default */
    status = 1; /* default error */

    ch = ignoreblks(f);

    if (EOF == ch) status = EOF;
    else if (isdigit(ch)) status = 0; /* digit, no error */

    while (isdigit(ch)) {
    digit = ch - '0';
    if ((value > UWARNLVL) ||
    ((UWARNLVL == value) && (digit > UWARNDIG))) {
    status = 1; /* overflow */
    value -= UWARNLVL;
    }
    value = 10 * value + digit;
    ch = getc(f);
    } /* while (ch is a digit) */

    *wd = value;
    ungetc(ch, f);
    return status;
    } /* readxwd */

    /*--------------------------------------------------------------
    * Read a signed value. Signal error for overflow or no valid
    * number found. Returns true for error, false for noerror. On
    * overflow either INT_MAX or INT_MIN is returned in *val.
    *
    * Skip all leading blanks on f. At completion getc(f) will
    * return the character terminating the number, which may be \n
    * or EOF among others. Barring EOF it will NOT be a digit. The
    * combination of error, 0 result, and the next getc returning
    * \n indicates that no numerical value was found on the line.
    *
    * If the user wants to skip all leading white space including
    * \n, \f, \v, \r, he should first call "skipwhite(f);"
    *
    * Peculiarity: an isolated leading '+' or '-' NOT immediately
    * followed by a digit will return error and a value of 0, when
    * the next getc will return that following non-digit. This is
    * caused by the single level ungetc available.
    */
    int readxint(int *val, FILE *f)
    {
    unsigned int value;
    int status, negative;
    int ch;

    *val = value = 0; /* default */
    status = 1; /* default error */
    negative = 0;

    ch = ignoreblks(f);

    if (EOF != ch) {
    if (('+' == ch) || ('-' == ch)) {
    negative = ('-' == ch);
    ch = ignoreblks(f); /* absorb any sign */
    }

    if (isdigit(ch)) { /* digit, no error */
    ungetc(ch, f);
    status = readxwd(&value, f);
    ch = getc(f); /* This terminated readxwd */
    }

    if (0 == status) {
    /* got initial digit and no readxwd overflow */
    if (!negative && (value <= INT_MAX))
    *val = value;
    else if (negative && (value < UINT_MAX) &&
    ((value - 1) <= -(1 + INT_MIN)))
    *val = -value;
    else { /* overflow */
    status = 1; /* do whatever the native system does */
    if (negative) *val = -value;
    else *val = value;
    }
    }
    else if (negative) *val = -value;
    else *val = value;
    }
    ungetc(ch, f);
    return status;
    } /* readxint */

    /*-----------------------------------------------------
    * Flush input through an end-of-line marker inclusive.
    */
    void flushln(FILE *f)
    {
    int ch;

    do {
    ch = getc(f);
    } while (('\n' != ch) && (EOF != ch));
    } /* flushln */

    /* End of txtinput.c */

    --
    Chuck F (cbfalconer at maineline dot net)
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net>
     
    CBFalconer, Nov 25, 2006
    #6
  7. CBFalconer <> wrote:
    > Jens Thoms Toerring wrote:
    > > wrote:
    > >> I'm trying to read positive integer number with the help of scanf,
    > >> if the input value is not positive number but negaive one zero or
    > >> char , i have to reread the input until I get the needed pos. number

    > >
    > >> I wrote the code , but it doesn't work the way it should : if i put
    > >> some char into input, the program goes infinite loop instead of
    > >> promting me to enter a new value.

    > >

    > ... snip code using scanf ...
    > >
    > > The scanf() in the while loop consumes all non-numerical input
    > > (except '+' and '-') and then the scanf() in the do loops
    > > condition tries to read in an integer. If that works and the
    > > number is positive the loop ends. If not we're back to square
    > > one. But there's still the problem that you can't check if the
    > > user input a number that's too large to be stored in an integer.
    > > Such checks can only be done using the approach mentioned first.
    > > And, of course, it also will return 123 for e.g. "asa%#123.12"
    > > (and leaves everything following the "123" in the input buffer)
    > > - I don't know if that's what you want.


    > ONLY be done? See the following. No buffers needed. Improved
    > since the published version. I am not completely happy with the
    > treatment of negative values in readxint. Also it needs to be
    > revised to use longs as the fundamental input mechanism. Note the
    > GPL licence.


    <code snipped>

    Thanks for the correction. What I actually wanted to warn the OP
    about is that using only scanf() it's impossible to do full error
    checking. As you have shown, using fgets() isn't the only method
    that can be used here. And your code is a good example of what one
    have to take into account to get it RIGHT;-) Unfortunately, when
    one has to read in floating point numbers it probably will become
    very difficult (or impossible?) to work with a single look-ahead
    character and I guess then some solution involving fgets() will be
    necessary. Or do you have a nice function also for that case?

    Regards, Jens
    --
    \ Jens Thoms Toerring ___
    \__________________________ http://toerring.de
     
    Jens Thoms Toerring, Nov 25, 2006
    #7
  8. CBFalconer Guest

    Jens Thoms Toerring wrote:
    > CBFalconer <> wrote:
    >

    .... snip ...
    >
    >> ONLY be done? See the following. No buffers needed. Improved
    >> since the published version. I am not completely happy with the
    >> treatment of negative values in readxint. Also it needs to be
    >> revised to use longs as the fundamental input mechanism. Note the
    >> GPL licence.

    >
    > <code snipped>
    >
    > Thanks for the correction. What I actually wanted to warn the OP
    > about is that using only scanf() it's impossible to do full error
    > checking. As you have shown, using fgets() isn't the only method
    > that can be used here. And your code is a good example of what one
    > have to take into account to get it RIGHT;-) Unfortunately, when
    > one has to read in floating point numbers it probably will become
    > very difficult (or impossible?) to work with a single look-ahead
    > character and I guess then some solution involving fgets() will be
    > necessary. Or do you have a nice function also for that case?


    It can be built around the routines I showed. The only problem is
    with exponential notation, otherwise 1 char lookahead does fine.
    The problem case is: "1.23ex" which requires 2 char lookahead, or 2
    level ungetc. scanf suffers from this too.

    --
    Chuck F (cbfalconer at maineline dot net)
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net>
     
    CBFalconer, Nov 25, 2006
    #8
  9. Guest

    Thanks for reply.
    I give it I try.
    If this method is working only on flavours of unix , it's fine with me.

    Ian Collins wrote:
    > Richard Heathfield wrote:
    > > Ian Collins said:
    > >
    > >
    > >>Add
    > >>
    > >>fflush( stdin );

    > >
    > >
    > > No, don't do that. The behaviour of fflush on streams open for input is
    > > undefined.
    > >

    > Oops, so it is.
    >
    > I've always used the Solaris man page definition:
    >
    > "If stream points to an input stream or an update stream into
    > which the most recent operation was input, that stream is
    > flushed if it is seekable and is not already at end-of-file."
    >
    > --
    > Ian Collins.
     
    , Nov 25, 2006
    #9
  10. Guest

    Thanks Jens .

    I have to use scanf() because of my task's constrains.
    Your work-around works fine, if "fflush(stdin)" idea from previuos post
    would fail,
    i would surely go for it.

    Thanks for the tip.

    Jens Thoms Toerring wrote:
    > wrote:
    > > I maybe reinvent the weel ...

    >
    > No, you just found out that scanf() is not very well suited for
    > dealing with user input. You're definitely not the first and
    > won't be the last;-)
    >
    > > I'm trying to read positive integer number with the help of scanf, if
    > > the input value is not positive number but negaive one zero or char , i
    > > have to reread the input until I get the needed pos. number

    >
    > > I wrote the code , but it doesn't work the way it should : if i put
    > > some char into input, the program goes infinite loop instead of
    > > promting me to enter a new value.

    >
    > > Please shed some light on what is the problem. thanks

    >
    > > #include <stdio.h>

    >
    > > int main()

    >
    > int main( void )
    >
    > tends to be better since your main() function doesn't take any input.
    >
    > > {
    > > int n;
    > > while (1)
    > > {
    > > printf("Please enter positive number \n");
    > > if ( scanf("%d",&n)!=1 || n<=0 )

    >
    > The problem you're facing is that when scanf() doesn't find what
    > it's looking for it won't read anything at all. So if the user inputs
    > something that doesn't start with a number (with optionally a '+' or
    > '-' in front of it) it stops immediately and nothing of the users
    > input gets consumed. When scanf() then tries to read again it still
    > finds the same characters it couldn't deal with already the last time
    > and bails out again. Repeat at nauseam...
    >
    > In this case there are two ways t deal with it. The probably saner
    > approach is to use a function like fgets() to read the input as a
    > string, analyze this string for a number you are prepared to accept,
    > and then to use e.g. strtol() to get at that number (which also allows
    > to do full error checking).
    >
    > But since you're here just looking for a positive integer there's
    > the following alternative:
    >
    > #include <stdio.h>
    >
    > int main( void )
    > {
    > char buffer[10];
    > int x ;
    >
    > do {
    > printf( "Please enter positive number\n" );
    > while ( scanf( "%9[^-+0-9]", buffer ) != 0 )
    > /* empty */ ;
    > } while ( scanf( "%d", &x ) != 1 || x <= 0 );
    > printf( "Got %d", x );
    > return 0;
    > }
    >
    > The scanf() in the while loop consumes all non-numerical input
    > (except '+' and '-') and then the scanf() in the do loops
    > condition tries to read in an integer. If that works and the
    > number is positive the loop ends. If not we're back to square
    > one. But there's still the problem that you can't check if the
    > user input a number that's too large to be stored in an integer.
    > Such checks can only be done using the approach mentioned first.
    > And, of course, it also will return 123 for e.g. "asa%#123.12"
    > (and leaves everything following the "123" in the input buffer)
    > - I don't know if that's what you want.
    >
    > Regards, Jens
    > --
    > \ Jens Thoms Toerring ___
    > \__________________________ http://toerring.de
     
    , Nov 25, 2006
    #10
  11. said:

    > Thanks for reply.
    > I give it I try.


    Why? It's wrong, broken, wrong, broken, wrong, wrong, wrong! Why would you
    use a wrong, broken, wrong, broken, wrong, wrong, wrong suggestion? Even
    the guy who suggested it now realises it's wrong, broken, wrong, broken,
    wrong, wrong, wrong.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at the above domain, - www.
     
    Richard Heathfield, Nov 25, 2006
    #11
  12. Guest

    I've tested "fflush( stdin );" on both WinXP and SunOS boxes it works
    without a glitch.


    wrote:
    > Thanks for reply.
    > I give it I try.
    > If this method is working only on flavours of unix , it's fine with me.
    >
    > Ian Collins wrote:
    > > Richard Heathfield wrote:
    > > > Ian Collins said:
    > > >
    > > >
    > > >>Add
    > > >>
    > > >>fflush( stdin );
    > > >
    > > >
    > > > No, don't do that. The behaviour of fflush on streams open for input is
    > > > undefined.
    > > >

    > > Oops, so it is.
    > >
    > > I've always used the Solaris man page definition:
    > >
    > > "If stream points to an input stream or an update stream into
    > > which the most recent operation was input, that stream is
    > > flushed if it is seekable and is not already at end-of-file."
    > >
    > > --
    > > Ian Collins.
     
    , Nov 25, 2006
    #12
  13. Ian Collins Guest

    Richard Heathfield wrote:
    > said:
    >
    >
    >>Thanks for reply.
    >>I give it I try.

    >
    >
    > Why? It's wrong, broken, wrong, broken, wrong, wrong, wrong! Why would you
    > use a wrong, broken, wrong, broken, wrong, wrong, wrong suggestion? Even
    > the guy who suggested it now realises it's wrong, broken, wrong, broken,
    > wrong, wrong, wrong.
    >

    Just curious, has fflush( stdin ) always been undefined, rather than
    implementation defined? The Solaris version makes sense to me.

    --
    Ian Collins.
     
    Ian Collins, Nov 25, 2006
    #13
  14. said:

    > I've tested "fflush( stdin );" on both WinXP and SunOS boxes it works
    > without a glitch.


    Try driving on the wrong side of the road. That works without a glitch too -
    mostly.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at the above domain, - www.
     
    Richard Heathfield, Nov 25, 2006
    #14
  15. Ian Collins said:

    <snip>

    > Just curious, has fflush( stdin ) always been undefined, rather than
    > implementation defined?


    Yes.

    > The Solaris version makes sense to me.


    How can flushing input make sense? You flush toilets, not taps.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at the above domain, - www.
     
    Richard Heathfield, Nov 25, 2006
    #15
  16. Ian Collins Guest

    Richard Heathfield wrote:
    > said:
    >
    >
    >>I've tested "fflush( stdin );" on both WinXP and SunOS boxes it works
    >>without a glitch.

    >
    >
    > Try driving on the wrong side of the road. That works without a glitch too -
    > mostly.
    >

    Especially if the signs tell you to! The operation may well be defined
    in XP as it is on Solaris.

    --
    Ian Collins.
     
    Ian Collins, Nov 25, 2006
    #16
  17. Ian Collins Guest

    Richard Heathfield wrote:
    > Ian Collins said:
    >
    >
    >>Just curious, has fflush( stdin ) always been undefined, rather than
    >>implementation defined?

    >
    > Yes.
    >
    >>The Solaris version makes sense to me.

    >
    > How can flushing input make sense? You flush toilets, not taps.
    >

    Well you flush beer pumps to clear out the stale beer.

    --
    Ian Collins.
     
    Ian Collins, Nov 25, 2006
    #17
  18. Ian Collins said:

    > Richard Heathfield wrote:
    >> said:
    >>
    >>
    >>>I've tested "fflush( stdin );" on both WinXP and SunOS boxes it works
    >>>without a glitch.

    >>
    >>
    >> Try driving on the wrong side of the road. That works without a glitch
    >> too - mostly.
    >>

    > Especially if the signs tell you to!


    The "signs", in C, are written in the Standard, and the Standard tells you
    not to. There is, in any case, a perfectly portable way to achieve the
    objective without invoking undefined behaviour.

    > The operation may well be defined in XP as it is on Solaris.


    That doesn't render the operation *correct*, though. Why not just do it
    right, instead of finding excuses to do it wrong?

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at the above domain, - www.
     
    Richard Heathfield, Nov 25, 2006
    #18
  19. Ian Collins said:

    > Richard Heathfield wrote:
    >> Ian Collins said:
    >>
    >>
    >>>Just curious, has fflush( stdin ) always been undefined, rather than
    >>>implementation defined?

    >>
    >> Yes.
    >>
    >>>The Solaris version makes sense to me.

    >>
    >> How can flushing input make sense? You flush toilets, not taps.
    >>

    > Well you flush beer pumps to clear out the stale beer.

    ^^^

    Flushing is an output operation. The Standard makes this clear. So does your
    claim about beer pumps, albeit non-normatively.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at the above domain, - www.
     
    Richard Heathfield, Nov 25, 2006
    #19
  20. Guest

    Richard , with all respect

    U haven't provided any reference for your claim that fflush( stdin ) is
    undefined, so for me
    they are still only your words and not "The Standard"

    Read this, for example :
    <>
    Standard C Library Functions fflush(3C)

    NAME
    fflush - flush a stream

    SYNOPSIS
    #include <stdio.h>

    int fflush(FILE *stream);

    DESCRIPTION
    If stream points to an output stream or an update stream in
    which the most recent operation was not input, fflush()
    causes any unwritten data for that stream to be written to
    the file, and the st_ctime and st_mtime fields of the under-
    lying file are marked for update.

    If stream is a null pointer, fflush() performs this flushing
    action on all streams for which the behavior is defined
    above. Additionally, an input stream or an update stream
    into which the most recent operation was input is also
    flushed if it is seekable and is not already at end-of-file.
    Flushing an input stream discards any buffered input and
    adjusts the file pointer such that the next input operation
    accesses the byte after the last one read. A stream is
    seekable if the underlying file is not a pipe, FIFO, socket,
    or TTY device. An input stream, seekable or non-seekable,
    can be flushed by explicitly calling fflush() with a non-
    null argument specifying that stream.
    <>

    Richard Heathfield wrote:
    > said:
    >
    > > I've tested "fflush( stdin );" on both WinXP and SunOS boxes it works
    > > without a glitch.

    >
    > Try driving on the wrong side of the road. That works without a glitch too -
    > mostly.
    >
    > --
    > Richard Heathfield
    > "Usenet is a strange place" - dmr 29/7/1999
    > http://www.cpax.org.uk
    > email: rjh at the above domain, - www.
     
    , Nov 25, 2006
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Rob Thorpe

    Correct behaviour of scanf and sscanf

    Rob Thorpe, Mar 14, 2005, in forum: C Programming
    Replies:
    6
    Views:
    467
    Dan Pop
    Mar 15, 2005
  2. Lalatendu Das

    confused about behaviour of scanf

    Lalatendu Das, Dec 21, 2005, in forum: C Programming
    Replies:
    33
    Views:
    1,044
    Dave Thompson
    Jan 4, 2006
  3. Scanf Behaviour

    , Dec 30, 2005, in forum: C Programming
    Replies:
    7
    Views:
    421
    Keyser Soze
    Dec 30, 2005
  4. =?ISO-8859-1?Q?Martin_J=F8rgensen?=

    scanf (yes/no) - doesn't work + deprecation errors scanf, fopen etc.

    =?ISO-8859-1?Q?Martin_J=F8rgensen?=, Feb 16, 2006, in forum: C Programming
    Replies:
    185
    Views:
    3,526
    those who know me have no need of my name
    Apr 3, 2006
  5. =?ISO-8859-1?Q?Martin_J=F8rgensen?=

    difference between scanf("%i") and scanf("%d") ??? perhaps bug inVS2005?

    =?ISO-8859-1?Q?Martin_J=F8rgensen?=, Apr 26, 2006, in forum: C Programming
    Replies:
    18
    Views:
    711
    Richard Bos
    May 2, 2006
Loading...

Share This Page