scanf - data is "put back" - screws up next scanf

This is a discussion on scanf - data is "put back" - screws up next scanf within the C Programming forums, part of the General Programming Boards category; Just starting to learn C - trying to figure out what this means exactly - "When scanf encouters a character ...

  1. #1
    Registered User
    Join Date
    Oct 2002
    Posts
    4

    scanf - data is "put back" - screws up next scanf

    Just starting to learn C - trying to figure out what this means exactly - "When scanf encouters a character that can't be part of the current item (in this case an array), the character is Put Back to be read again during the scanning of the next input item or during the next call of scanf. "

    I wrote this program to see what would happen if i entered too many numbers on the same line before hitting the enter key. I then did two more scanf() functions and print() and the data that was "put back" because i entered 12 integers instead of only 10 automatically is printed out. I'm just trying to understand how scanf works with the "buffer" that it goes to. Any insight into how this works would be great. I've read that leaving a space before the conversion specifier (%d here) is necessary because if you don't the "newline" character will be read by scanf the next time it's called.

    /***********************************************/

    Code:
    #include<stdio.h>
    
    main()
    {
    	int a, b, c, d[10];
    
    		printf( "Please enter 10 numbers: \n" );
    	
    	for ( b = 0; b < 10; b++)
    	{
    		scanf( " %d", &d[b] );
    	}
    	
    	printf( "Here are the numbers you entered: \n\n" );
    
    	for ( b = 0; b < 10; b++)		
    		printf( "%d ", d[b] );
    
    	printf( "\n\nPlease enter another number: " );
    	scanf( "  %d", &a );
    
    	printf( "\n\n %d \n\n", a );
    
    		printf( "\n\nPlease enter another number: " );
    	scanf( " %d", &c );
    
    	printf( "\n\n %d \n\n", c );
    	
    	return 0;
    }
    Last edited by voltson; 10-09-2002 at 08:10 PM.

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You will never see what gets 'put back'. Basicly what happens is this:

    You have an input stream that is used for reading input from your device of choice (commonly the keyboard). It stores the input until you happen to read it so you can do something with it.

    Scanf basicly does:

    "%d" == scan the input stream and pull the number

    So, if your input stream is:

    "123 asdf"

    The %d call to scanf tells it to start pulling characters from the input stream until it encounters something that isn't a number. When it encounters something that isn't a number, it puts it back so the next function that reads from the input stream will get the correct data. Illustrated, it looks like:

    read a character, the 1 (the rest is '23 asdf')
    read a character, the 2 (the rest is '3 asdf)
    read a character, the 3 (the rest is ' asdf')
    read a character, the space ... since this isn't a number, it has to put it back into the input stream so the next read will work right.

    Quzah.
    Last edited by quzah; 10-09-2002 at 08:11 PM.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    Oct 2002
    Posts
    4
    Thanks for the ultrafast response Quzah.

    Apparently you do see what is put back after scanf() in this case. It sees that it cannot use the extra elements of the array (declared as 10 element array) if i run it and type 12 numbers on the same line before pressing enter, seems the 11, and 12 are still in the buffer and are read when scanf() is called again.


    Please enter 10 numbers:
    1 2 3 4 5 6 7 8 9 10 11 12
    Here are the numbers you entered:

    1 2 3 4 5 6 7 8 9 10

    Please enter another number:

    11



    Please enter another number:

    12

    Press any key to continue

    -------------

    It doesn't even give me a chance to type a number to either of the scanf() functions.

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    What I meant was that you can't see the actual process of it putting it back. You don't see when:

    123abc
    it reads 123
    it reads a and finds out that a isn't a number

    You don't see the phase where 'a' is not on the input stream. The actual put-back process ( look at ungetc for a reference ) is hidden from your eyes. You don't actually see when it strips the a off and then puts it back. Sure you can see the stuff in the buffer later if you call other functions, but you don't see the actual over-read / put-back process happen. It is transparent.

    That's what I was talking about.

    Quzah.
    Hope is the first step on the road to disappointment.

  5. #5
    Registered User Azuth's Avatar
    Join Date
    Feb 2002
    Posts
    236
    I could be wrong, but it appears that you're talking at cross purposes. I take from quzah's post that scanf will hold those items in the buffer you just don't see the actual process, I don't know if I'd expect them to remain there very long, I don't know much about the actual buffer *shrug.

    You can clear stdin before doing a scanf to make sure there's nothing floating around in there (if you really want the extra info users are entering make you array take 12 elements ).

    Something like
    Code:
    while ( getchar() != '\n' );
    will do the job in most cases. (well, O.K. most in my lmited encounters).

    fflush (stdin) will just incur the wrath of Prelude, forget undefined behaviour, fear the wrath of Prelude.

    [edit]
    OK. I take from quzah's first post. Dammit quzah, you're too on the ball
    [/edit]
    Demonographic rhinology is not the only possible outcome, but why take the chance

  6. #6
    Registered User
    Join Date
    Oct 2002
    Posts
    4
    Thanks for the clarification - always good to have more than one wording of something.

  7. #7
    Black Mage Extraordinaire VegasSte's Avatar
    Join Date
    Oct 2002
    Posts
    167
    >fflush (stdin) will just incur the wrath of Prelude, forget undefined behaviour, fear the wrath of Prelude.

    Why? What is wrong with this?
    Being a C newbie I am non-plussed

  8. #8
    Registered User Azuth's Avatar
    Join Date
    Feb 2002
    Posts
    236
    Vegas, take a look here....

    weird scanf()

    You could also search the board for scanf AND fflush (stdin), or something similar.

  9. #9
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    Originally posted by VegasSte
    >fflush (stdin) will just incur the wrath of Prelude, forget undefined behaviour, fear the wrath of Prelude.

    Why? What is wrong with this?
    Being a C newbie I am non-plussed
    ... and the official answer... (not that you doubt Prelude's words, I'm sure )
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  10. #10
    Black Mage Extraordinaire VegasSte's Avatar
    Join Date
    Oct 2002
    Posts
    167
    Doubt Prelude, not at all
    I am just curious by nature and being a C newbie I do not understand!!

  11. #11
    Banned Troll_King's Avatar
    Join Date
    Oct 2001
    Posts
    1,784
    while (getchar() != '\n') continue;

    As stated above or else:

    int ch;
    while ( (ch = getchar()) != EOF && ch != '\n') continue;
    Last edited by Troll_King; 10-14-2002 at 05:37 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Lame null append cause buffer to crash
    By cmoo in forum C Programming
    Replies: 8
    Last Post: 12-29-2008, 03:27 AM
  2. Unknown memory leak with linked lists...
    By RaDeuX in forum C Programming
    Replies: 6
    Last Post: 12-07-2008, 04:09 AM
  3. Replies: 3
    Last Post: 04-18-2008, 11:06 AM
  4. gcc problem
    By bjdea1 in forum Linux Programming
    Replies: 13
    Last Post: 04-29-2002, 07:51 PM
  5. How do I base size of arrays on annother number?
    By Dual-Catfish in forum C++ Programming
    Replies: 15
    Last Post: 09-25-2001, 02:31 PM

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