confused about behaviour of scanf

Discussion in 'C Programming' started by Lalatendu Das, Dec 21, 2005.

  1. Dear friends,
    I am getting a problem in the code while interacting with a nested
    Do-while loop
    It is skipping a scanf () function which it should not. I have written
    the whole code below. Please help me in finding why such thing is
    happening and what the remedy to it is. Kindly bear with my English.


    int
    main ()
    {
    int num1[4] , i = 0 ;
    char ch ;

    do
    {
    do
    {
    printf ("Enter the number in the array \n");
    scanf("%d",&num );
    i++;
    } while (i<=3);

    printf("Do u want to refill the array again y/n
    \n");
    scanf ("%c", &ch); /* This line is skipped, it
    is not
    prompting to
    give input
    from keyboard
    */

    } while (ch = = 'y') ; /* In gdb 'ch' is
    showing the value same as
    it has at the time of declaration i.e.
    some garbage */

    return 0;
    }

    I know this is very silly question for many of u but still I am in
    ambiguity to resolve it . So please send me all possible way of
    resolving it. and why such problem occurring. The environment in which
    I have done it is gcc-3.2.2, red hat Linux -9 , debugged using gdb .
    Lalatendu Das, Dec 21, 2005
    #1
    1. Advertising

  2. Lalatendu Das

    alok Guest

    add fflush(stdin) to clear input buffer

    int main ()
    {
    int num[4] , i = 0 ;
    char ch ;

    do
    {
    do
    {
    printf ("Enter the number in the array \n");
    scanf("%d",&num );
    i++;
    } while (i<=3);

    fflush(stdin);
    printf("Do u want to refill the array again y/n\n");
    scanf ("%c", &ch);
    } while (ch == 'y') ;

    return 0;

    }
    alok, Dec 21, 2005
    #2
    1. Advertising

  3. Lalatendu Das

    Jordan Abel Guest

    On 2005-12-21, alok <> wrote:
    > add fflush(stdin) to clear input buffer


    No.
    Jordan Abel, Dec 21, 2005
    #3
  4. Lalatendu Das

    Matt Guest

    Hi Lalatendu,

    There's a '\n' remainning in input stream after the outer loop, it then
    was read by scanf ("%c", &ch). (you can see it in gdb just after this
    line).

    You can use fflush(stdin) to clean the unwanted '\n' before scanf next
    value.

    Matt
    Matt, Dec 21, 2005
    #4
  5. Lalatendu Das

    Artie Gold Guest

    Matt wrote:
    > Hi Lalatendu,
    >
    > There's a '\n' remainning in input stream after the outer loop, it then
    > was read by scanf ("%c", &ch). (you can see it in gdb just after this
    > line).
    >
    > You can use fflush(stdin) to clean the unwanted '\n' before scanf next
    > value.
    >
    > Matt
    >

    Well, it looks like we're two-for-two on answers to this thread (but at
    least *this* poster found part of the solution.

    fflush() is only defined for *output* streams. In this case a simple
    getc() would suffice to read (and discard) the trailing newline character.

    Just as an aside, this is one of the reasons why scanf() shoul dprobably
    be avoided in most cases. A call to fgets() followed by a call to
    sscanf() is typically preferred.

    HTH,
    --ag

    --
    Artie Gold -- Austin, Texas
    http://goldsays.blogspot.com
    http://www.cafepress.com/goldsays
    "If you have nothing to hide, you're not trying!"
    Artie Gold, Dec 21, 2005
    #5
  6. Lalatendu Das

    Michael Mair Guest

    Lalatendu Das wrote:
    > Dear friends,
    > I am getting a problem in the code while interacting with a nested
    > Do-while loop
    > It is skipping a scanf () function which it should not. I have written
    > the whole code below. Please help me in finding why such thing is
    > happening and what the remedy to it is. Kindly bear with my English.
    >
    >
    > int
    > main ()
    > {
    > int num1[4] , i = 0 ;
    > char ch ;
    >
    > do
    > {
    > do
    > {
    > printf ("Enter the number in the array \n");
    > scanf("%d",&num );
    > i++;
    > } while (i<=3);
    >
    > printf("Do u want to refill the array again y/n
    > \n");
    > scanf ("%c", &ch); /* This line is skipped, it
    > is not
    > prompting to
    > give input
    > from keyboard
    > */
    >
    > } while (ch = = 'y') ; /* In gdb 'ch' is
    > showing the value same as
    > it has at the time of declaration i.e.
    > some garbage */
    >
    > return 0;
    > }
    >
    > I know this is very silly question for many of u but still I am in
    > ambiguity to resolve it . So please send me all possible way of
    > resolving it. and why such problem occurring. The environment in which
    > I have done it is gcc-3.2.2, red hat Linux -9 , debugged using gdb .


    See the comp.lang.c FAQ 12.17, 12.18a, 12.19, 12.20 and search
    the comp.lang.c archives.

    Note: fflush(stdin) is _not_ the solution. getchar() can be.

    Cheers
    Michael
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.
    Michael Mair, Dec 21, 2005
    #6
  7. Lalatendu Das

    alok Guest

    i m running this program in MS VC++ & after using fflush(stdin) , it
    is working fine .
    so y fflush(stdin) is _not_ the solution ?
    alok, Dec 21, 2005
    #7
  8. Lalatendu Das

    alok Guest

    i m running this program in MS VC++ & Solaris gcc after using
    fflush(stdin) , it is working fine .
    so y fflush(stdin) is _not_ the solution ?
    alok, Dec 21, 2005
    #8
  9. Lalatendu Das

    Anand Guest

    [Corrected quoting]
    --- Quoting from others ---------
    <Quote>
    It is proper Usenet etiquette to include the relevant portions of the
    text you are replying to. To do this using Google groups, please follow
    the instructions below, penned by Keith Thompson:

    If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers.
    </Quote>

    alok wrote:
    > Michael Mair wrote:
    >> See the comp.lang.c FAQ 12.17, 12.18a, 12.19, 12.20 and search
    >> the comp.lang.c archives.
    >>
    >> Note: fflush(stdin) is _not_ the solution. getchar() can be.
    >>
    >> Cheers
    >> Michael

    >
    > i m running this program in MS VC++ & Solaris gcc after using
    > fflush(stdin) , it is working fine .
    > so y fflush(stdin) is _not_ the solution ?
    >


    Because the standard says so
    C99 7.19.5.2
    "
    Ifstream points to an output stream or an update stream in which the
    most recent operation was not input, the fflush function causes any
    unwritten data for that stream to be delivered to the host environment
    to be written to the file; otherwise, the behavior is undefined.
    "

    Since it is undefined anything can happen. It might be working for you
    now and it might be the feature of the compiler not the language.

    --
    (Welcome) http://www.ungerhu.com/jxh/clc.welcome.txt
    (clc FAQ) http://www.eskimo.com/~scs/C-faq/top.html
    Anand, Dec 21, 2005
    #9
  10. In article <>,
    alok <> wrote:
    >i m running this program in MS VC++ & after using fflush(stdin) , it
    >is working fine .
    >so y fflush(stdin) is _not_ the solution ?


    Welcome to clc.
    Kenny McCormack, Dec 21, 2005
    #10
  11. Lalatendu Das

    pemo Guest

    "Anand" <> wrote in message
    news:059qf.1$...
    > [Corrected quoting]
    > --- Quoting from others ---------
    > <Quote>
    > It is proper Usenet etiquette to include the relevant portions of the text
    > you are replying to. To do this using Google groups, please follow the
    > instructions below, penned by Keith Thompson:
    >
    > If you want to post a followup via groups.google.com, don't use
    > the broken "Reply" link at the bottom of the article. Click on
    > "show options" at the top of the article, then click on the
    > "Reply" at the bottom of the article headers.
    > </Quote>
    >
    > alok wrote:
    > > Michael Mair wrote:
    > >> See the comp.lang.c FAQ 12.17, 12.18a, 12.19, 12.20 and search
    > >> the comp.lang.c archives.
    > >>
    > >> Note: fflush(stdin) is _not_ the solution. getchar() can be.
    > >>
    > >> Cheers
    > >> Michael

    > >
    >> i m running this program in MS VC++ & Solaris gcc after using
    >> fflush(stdin) , it is working fine .
    >> so y fflush(stdin) is _not_ the solution ?
    >>

    >
    > Because the standard says so
    > C99 7.19.5.2
    > "
    > Ifstream points to an output stream or an update stream in which the most
    > recent operation was not input, the fflush function causes any unwritten
    > data for that stream to be delivered to the host environment to be written
    > to the file; otherwise, the behavior is undefined.
    > "
    >
    > Since it is undefined anything can happen. It might be working for you now
    > and it might be the feature of the compiler not the language.


    It would be sooo simple if there were a way to test stdin for
    eof/empty-buffer :)
    pemo, Dec 21, 2005
    #11
  12. On 21 Dec 2005 00:29:21 -0800, "alok" <> wrote:

    >i m running this program in MS VC++ & after using fflush(stdin) , it
    >is working fine .
    >so y fflush(stdin) is _not_ the solution ?


    it s nt the sltn because fflush is defined only for output streams .
    Calling fflush for an input stream invokes undefined behavior. One of
    the unluckiest manifestations of undefined behavior is the appearance
    of working as expected and thereby misleading you to think it is
    correct. This usually lasts until you have to demo the product to
    your boss or a client.

    The discussion of MS VC++ features/anomalies/ is properly done in one
    of the microsoft.*.* groups. This group is about standard C


    <<Remove the del for email>>
    Barry Schwarz, Dec 21, 2005
    #12
  13. Lalatendu Das

    Ed Prochak Guest

    pemo wrote:
    > "Anand" <> wrote in message
    > news:059qf.1$...

    []
    > >
    > > alok wrote:

    []
    > >> i m running this program in MS VC++ & Solaris gcc after using
    > >> fflush(stdin) , it is working fine .
    > >> so y fflush(stdin) is _not_ the solution ?
    > >>

    > >
    > > Because the standard says so
    > > C99 7.19.5.2

    []
    >
    > It would be sooo simple if there were a way to test stdin for
    > eof/empty-buffer :)


    There is
    while ( !fgets( buffer, size, STDIN) ) { ...
    or
    while ( !(nextch=getchar()) ) { ...

    Do people not read the documentation of the functions they use?


    ed
    Ed Prochak, Dec 21, 2005
    #13
  14. Lalatendu Das

    Flash Gordon Guest

    Ed Prochak wrote:
    > pemo wrote:
    >> "Anand" <> wrote in message
    >> news:059qf.1$...

    > []
    >>> alok wrote:

    > []
    >>>> i m running this program in MS VC++ & Solaris gcc after using
    >>>> fflush(stdin) , it is working fine .
    >>>> so y fflush(stdin) is _not_ the solution ?
    >>>>
    >>> Because the standard says so
    >>> C99 7.19.5.2

    > []
    >> It would be sooo simple if there were a way to test stdin for
    >> eof/empty-buffer :)

    >
    > There is
    > while ( !fgets( buffer, size, STDIN) ) { ...
    > or
    > while ( !(nextch=getchar()) ) { ...


    Neither of your suggestions tests for an empty buffer for an empty
    buffer since the functions you are calling will just sit there until
    either there is something in the buffer or they detect an end-of-file or
    error condition. Your use of getchar is completely wrong, since it
    returns EOF, not 0, or either end-of-file or error. You don't attempt to
    distinguish between an error and end-of-file (which can be done).

    > Do people not read the documentation of the functions they use?


    Obviously not.

    Standard C provides no mechanism for detecting whether there is anything
    in the buffer ready to be read, which I consider to be a shame. It
    would, IMHO, be useful if standard C had a bufempty function with four
    return values, empty, non-empty, full and unknown, but it does not exist
    in standard C.
    --
    Flash Gordon
    Living in interesting times.
    Although my email address says spam, it is real and I read it.
    Flash Gordon, Dec 21, 2005
    #14
  15. Lalatendu Das

    Michael Mair Guest

    Ed Prochak wrote:
    > pemo wrote:
    >
    >>"Anand" <> wrote in message
    >>news:059qf.1$...

    >
    > []
    >
    >>>alok wrote:

    >
    > []
    >
    >>>>i m running this program in MS VC++ & Solaris gcc after using
    >>>>fflush(stdin) , it is working fine .
    >>>>so y fflush(stdin) is _not_ the solution ?
    >>>>
    >>>
    >>>Because the standard says so
    >>>C99 7.19.5.2

    >
    > []
    >
    >>It would be sooo simple if there were a way to test stdin for
    >>eof/empty-buffer :)

    >
    >
    > There is
    > while ( !fgets( buffer, size, STDIN) ) { ...

    ITYM: stdin
    > or
    > while ( !(nextch=getchar()) ) { ...

    ITYM: EOF != (nextch = getchar())

    > Do people not read the documentation of the functions they use?


    "Real men don't need to read the manual" or, in this case, the
    documentation... ;-(

    Cheers
    Michael
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.
    Michael Mair, Dec 21, 2005
    #15
  16. Lalatendu Das

    Michael Mair Guest

    alok wrote:
    > i m running this program in MS VC++ & Solaris gcc after using
    > fflush(stdin) , it is working fine .
    > so y fflush(stdin) is _not_ the solution ?


    Apart from the missing context: Please try to write something
    resembling written English, especially write whole words.

    As others have told you: fflush(stdin) has no defined behaviour
    from the standard C point of view.

    Slighty off-topic example:
    Consider the many breaking changes from MSVC++6 to
    MSVC++2003 and 2005 which nearly all concern the change from
    not standard-conforming to standard-conforming behaviour (especially
    for the C++ part). If the people relying on non-standard stuff had
    written the things as standard-conforming as possible, they would
    not have had to rewrite huge parts of their code.

    So, as there exists a perfectly portable and viable solution to
    your problem, it is reasonable to use it instead of a solution
    which may not work after a change of platform, operating system,
    compiler or even compiler version.

    Cheers
    Michael
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.
    Michael Mair, Dec 21, 2005
    #16
  17. "Ed Prochak" <> writes:
    > pemo wrote:
    >> "Anand" <> wrote in message
    >> news:059qf.1$...

    > []
    >> >
    >> > alok wrote:

    > []
    >> >> i m running this program in MS VC++ & Solaris gcc after using
    >> >> fflush(stdin) , it is working fine .
    >> >> so y fflush(stdin) is _not_ the solution ?
    >> >>
    >> >
    >> > Because the standard says so
    >> > C99 7.19.5.2

    > []
    >>
    >> It would be sooo simple if there were a way to test stdin for
    >> eof/empty-buffer :)

    >
    > There is
    > while ( !fgets( buffer, size, STDIN) ) { ...
    > or
    > while ( !(nextch=getchar()) ) { ...


    Which, as others have pointed out, doesn't check for an empty buffer.

    A feature I've seen elsewhere is the ability to flush the input buffer
    before reading input after a prompt. For example, given:

    printf("Enter a string: ");
    fflush(stdout); /* make sure the prompt appears */
    flush_input_buffer(stdin);
    fgets(s, LEN, stdin);

    any characters typed by the user before the prompt appears would be
    discarded. Ordinarily they'd be saved in the typeahead buffer; if the
    user guessed wrong about wnat the next prompt was going to be, bad
    things could happen.

    C provides no standard way to do this, mostly because it doesn't
    assume stdin is an interactive device such as a keyboard. <OT>I've
    used systems that had this feature; I think it was FLUSH(INPUT); in
    UCSD PAscal.</OT>

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
    Keith Thompson, Dec 21, 2005
    #17
  18. Lalatendu Das

    John Bode Guest

    Lalatendu Das wrote:
    > Dear friends,
    > I am getting a problem in the code while interacting with a nested
    > Do-while loop
    > It is skipping a scanf () function which it should not. I have written
    > the whole code below. Please help me in finding why such thing is
    > happening and what the remedy to it is. Kindly bear with my English.
    >
    >


    The problem is that you have a stray newline character stuck in the
    input stream after the first scanf(). For example, suppose you type
    1234 at the prompt and hit Return. The input stream then contains the
    characters '1', '2', '3', '4', and '\n'. The "%d" conversion specifier
    tells scanf() to skip any leading whitespace, and to read and convert
    all numeric (decimal) characters up to the first non-numeric character.
    So the first scanf() reads the '1', '2', '3', and '4' characters from
    the input stream and stops. This leaves the '\n' character still in
    the input stream. The "%c" conversion specifier tells scanf() to read
    and assign the next character. So the second scanf() call sees the
    '\n' in the input stream and assigns it to ch, but to you it looks like
    the second scanf() is being skipped.

    There are several ways around this. The simplest option is to change
    the second scanf() to use the "%s" conversion specifier and read a
    string instead of a single character. The "%s" conversion specfier
    will skip any leading whitespace, so stray newlines won't cause
    problems (however, other stray characters might; that's a different
    thread, though). It means changing ch from a single char to an array,
    but that's no big deal:

    char ch[2];
    ....
    printf("Do you want to refill the array again y/n: ");
    fflush(stdout);
    scanf("%1s", ch);
    if (ch[0] == 'y')
    {
    ...
    }

    It's not a robust solution, but it'll get you past this particular
    issue.

    > int
    > main ()
    > {
    > int num1[4] , i = 0 ;
    > char ch ;
    >
    > do
    > {
    > do
    > {
    > printf ("Enter the number in the array \n");
    > scanf("%d",&num );
    > i++;
    > } while (i<=3);
    >
    > printf("Do u want to refill the array again y/n
    > \n");
    > scanf ("%c", &ch); /* This line is skipped, it
    > is not
    > prompting to
    > give input
    > from keyboard
    > */
    >
    > } while (ch = = 'y') ; /* In gdb 'ch' is
    > showing the value same as
    > it has at the time of declaration i.e.
    > some garbage */
    >
    > return 0;
    > }
    >
    > I know this is very silly question for many of u but still I am in
    > ambiguity to resolve it . So please send me all possible way of
    > resolving it. and why such problem occurring. The environment in which
    > I have done it is gcc-3.2.2, red hat Linux -9 , debugged using gdb .
    John Bode, Dec 21, 2005
    #18
  19. Lalatendu Das

    Guest

    Lalatendu Das wrote:
    > Dear friends,
    > I am getting a problem in the code while interacting with a nested
    > Do-while loop
    > It is skipping a scanf () function which it should not. I have written
    > the whole code below. Please help me in finding why such thing is
    > happening and what the remedy to it is. Kindly bear with my English.
    >
    >
    > int
    > main ()
    > {
    > int num1[4] , i = 0 ;
    > char ch ;
    >
    > do
    > {
    > do
    > {
    > printf ("Enter the number in the array \n");
    > scanf("%d",&num );
    > i++;
    > } while (i<=3);
    >
    > printf("Do u want to refill the array again y/n
    > \n");
    > scanf ("%c", &ch); /* This line is skipped, it
    > is not
    > prompting to
    > give input
    > from keyboard
    > */
    >
    > } while (ch = = 'y') ; /* In gdb 'ch' is
    > showing the value same as
    > it has at the time of declaration i.e.
    > some garbage */
    >
    > return 0;
    > }
    >
    > I know this is very silly question for many of u but still I am in
    > ambiguity to resolve it . So please send me all possible way of
    > resolving it. and why such problem occurring. The environment in which
    > I have done it is gcc-3.2.2, red hat Linux -9 , debugged using gdb .


    what if we use
    scanf ("% c", &ch); //using a space between % and c
    Does this help to eliminate the new line charater in the buffer????
    , Dec 21, 2005
    #19
  20. Alok
    whatever u have suggested is the same which came to my mind
    also . but it fails when tried . it might work in vc++ or any other
    but in redhat linux 9/ gcc 3.2.2 (as i have mentioned before) it fails
    to work . so i need a solution which work for everything.

    And have also asked one of my teacher about this then , he told me to
    scan a pointer using fgets(). just before scanf it will eradicate the
    problem .
    char *test ;
    test = (char *) malloc(11);
    fgets( test , 11 , stdin);
    though this works but this is not a rsonable and genuine way to
    eradiacate the problem as where i will implement such things it will
    going to change the design .
    Lalatendu Das, Dec 22, 2005
    #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:
    437
    Dan Pop
    Mar 15, 2005
  2. Scanf Behaviour

    , Dec 30, 2005, in forum: C Programming
    Replies:
    7
    Views:
    400
    Keyser Soze
    Dec 30, 2005
  3. =?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,336
    those who know me have no need of my name
    Apr 3, 2006
  4. Argento

    scanf(), ungetc() behaviour.

    Argento, Mar 3, 2006, in forum: C Programming
    Replies:
    62
    Views:
    1,517
  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:
    656
    Richard Bos
    May 2, 2006
Loading...

Share This Page