What happens?

This is a discussion on What happens? within the C Programming forums, part of the General Programming Boards category; Code: #include <stdio.h> int main() { int x; do { scanf("%d",&x); printf("The number is %d\n",x); } while (x != 0); ...

  1. #1
    Registered User
    Join Date
    Jun 2009
    Posts
    452

    What happens?

    Code:
    #include <stdio.h>
    
    int main()
    {
      int x;
      do
      {
        scanf("%d",&x);
        printf("The number is %d\n",x);
      } while (x != 0);
    }
    This is just a really simple do-while loop. What I am curious about is what happens when you enter a non-integer number. For example if you enter a character, say 'r' from the keyboard. If you do this at the first call, it prints

    Code:
    The number is 0
    and then exits, which just means that x happened to be 0 already. If x wasn't 0, or if you enter a valid number first, say 4 on the first iteration, and then 'r' on the next, it will go into an infinite loop and print
    Code:
     
    The number is 4
    The number is 4
    The number is 4
    The number is 4
    The number is 4
    .
    .
    .
    forever.

    What exactly is happening? Why does it skip the scanf and not allow another entry when a non-integer character is input? I suspect that I am in undefined behaviour land here, but does anyone know?
    Last edited by KBriggs; 07-02-2009 at 09:19 AM.

  2. #2
    Super Moderator
    Join Date
    Sep 2001
    Posts
    4,913
    scanf reads data in from the operating system's input buffer. When you enter 4, it reads the 4 and passed it to your program, but the 4 is still in your input buffer, so the next time you call scanf, it doesn't wait for you to enter anything - to scanf it looks like you just entered '4'. You'll want to read up on how to flush the buffer (the FAQ entry on this site is pretty good). It's not exactly "undefined" - I'd say it's more OS-dependant. You won't find a standard solution that works across the board.

  3. #3
    gcc -Wall -pedantic *.c
    Join Date
    Jan 2009
    Location
    London
    Posts
    60
    You should also check the value that scanf returns. It in fact tells you how many parameters have been correctly read. if you put 'x' and your scanf waits for an integer (%d) it will return 0, so if you check scanf result you can avoid some strange behavior.

  4. #4
    DESTINY BEN10's Avatar
    Join Date
    Jul 2008
    Location
    in front of my computer
    Posts
    804
    Quote Originally Posted by sean View Post
    scanf reads data in from the operating system's input buffer. When you enter 4, it reads the 4 and passed it to your program, but the 4 is still in your input buffer, so the next time you call scanf, it doesn't wait for you to enter anything - to scanf it looks like you just entered '4'. You'll want to read up on how to flush the buffer (the FAQ entry on this site is pretty good). It's not exactly "undefined" - I'd say it's more OS-dependant. You won't find a standard solution that works across the board.
    What you are saying here, I think, is not applicable in this case. For eg. if I input 4, then according to you 4 should be in the buffer and it should continuosly print 4(as the call to next scanf also reads it), but what's happening here is it asks for the next input and so on until we enter a 0. The main problem is when we enter an integer and after that any character then it prints the integer indefinitely(i.e it is printing the last correct input indefinitely).
    I actually myself is confused what is happening in this case but to avoid this thing what flexo has advised is better. There should be an error check whether the input is actually an integer or not.
    HOPE YOU UNDERSTAND.......

    By associating with wise people you will become wise yourself
    It's fine to celebrate success but it is more important to heed the lessons of failure
    We've got to put a lot of money into changing behavior


    PC specifications- 512MB RAM, Windows XP sp3, 2.79 GHz pentium D.
    IDE- Microsoft Visual Studio 2008 Express Edition

  5. #5
    DESTINY BEN10's Avatar
    Join Date
    Jul 2008
    Location
    in front of my computer
    Posts
    804
    This is how I've modified the code.
    Code:
    #include <stdio.h>
    int main()
    {
      int x,i;
      do
      {
        i=scanf("%d",&x);
    	if(i==1)
        printf("The number is %d\n",x);
    	else
    		break;
      } while (x != 0);
    }
    HOPE YOU UNDERSTAND.......

    By associating with wise people you will become wise yourself
    It's fine to celebrate success but it is more important to heed the lessons of failure
    We've got to put a lot of money into changing behavior


    PC specifications- 512MB RAM, Windows XP sp3, 2.79 GHz pentium D.
    IDE- Microsoft Visual Studio 2008 Express Edition

  6. #6
    Registered User
    Join Date
    Jun 2009
    Posts
    452
    Thanks, but I know how to do most of that - this isn't a coding problem, just my own curiosity. My big question is this: after entering a non-integer, why does scanf not pause execution anymore until I enter a new entry?

  7. #7
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,246
    The problem is that scanf() is failing to parse out any characters from the input buffer. It leaves those characters in the input buffer which is what is causing your infinite loop. This is why it is a good idea to check the return value of scanf().

  8. #8
    Registered User
    Join Date
    Jun 2009
    Posts
    452
    Cool, thanks This kindof thing keeps cropping up in my codes when I try to use do-while loops to get input - ill use that check from now on.

  9. #9
    Registered User
    Join Date
    Jun 2009
    Posts
    452
    Sorry to double post, but this actually came up now. How do you flush the standard input? fflush(stdin) is undefined is it not?

  10. #10
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,537
    Quote Originally Posted by sean View Post
    scanf reads data in from the operating system's input buffer. When you enter 4, it reads the 4 and passed it to your program, but the 4 is still in your input buffer, so the next time you call scanf, it doesn't wait for you to enter anything - to scanf it looks like you just entered '4'. You'll want to read up on how to flush the buffer (the FAQ entry on this site is pretty good). It's not exactly "undefined" - I'd say it's more OS-dependant. You won't find a standard solution that works across the board.
    But there is a standard solution.

    Quote Originally Posted by KBriggs View Post
    Sorry to double post, but this actually came up now. How do you flush the standard input? fflush(stdin) is undefined is it not?
    Flushing buffer
    One of many examples.
    And yes, fflush(stdin) is undefined.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

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