Thread: scanf and EOF

  1. #1
    Registered User
    Join Date
    Dec 2012
    Posts
    10

    scanf and EOF

    hey
    I'm new to c and programming in general and there's something I can't figure out. I was hoping you could help me.

    I'm writing a program (home work) that supposed to receive a list of 5 digit IDs from the keyboard (for unlimited and unknown number of IDs) and then print an error for any ID which has a character in it (like a letter or anything else that is not a number).
    I've been trying to do it with scanf (%d) and a while loop with an EOF. and it's simply not working.
    I basically have a problem with illegal input. I don't understand how scanf behaves if it supposed to receive and integer and it gets something like 12a34.
    I need it to print an error and then go on with the next ID.
    any help?

  2. #2
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    Quote Originally Posted by littlerunaway View Post
    I've been trying to do it with scanf (%d) and a while loop with an EOF. and it's simply not working.
    I basically have a problem with illegal input. I don't understand how scanf behaves if it supposed to receive and integer and it gets something like 12a34.
    scanf(%d) stops at the first character which isn't a number and leaves that character (in your example 'a') in the input stream. Thus if you try to use scanf(%d) another time (at your next iteration) it will still stop at that character and will never move on.

    Quote Originally Posted by littlerunaway View Post
    I need it to print an error and then go on with the next ID.
    In order to continue your program you need to find a way to get rid of the wrong characters left in the input stream. Read about flushing the input stream.

    Bye, Andreas

  3. #3
    Registered User
    Join Date
    Dec 2012
    Posts
    10
    Quote Originally Posted by AndiPersti View Post
    scanf(%d) stops at the first character which isn't a number and leaves that character (in your example 'a') in the input stream. Thus if you try to use scanf(%d) another time (at your next iteration) it will still stop at that character and will never move on.


    In order to continue your program you need to find a way to get rid of the wrong characters left in the input stream. Read about flushing the input stream.

    Bye, Andreas
    that's why I got an infinite loop. I see. I can't really use those methods to get rid of the unwanted data cuz they don't really let us use things we haven't learnt in class yet.

    I actually wrote first the program using the getchar() function which worked better but turned out to be longer.

    anyway, another question.
    in my current program when I press the "enter" after some input it starts the execution of the program. is there a way to make it so that "enter" will simply request more input on the next line and execution starts only after CTRL+z (EOF)?
    meaning if I want to input the ID numbers with an "enter" between them rather than on the same line (I hope I'm being clear, English is not my first language).

  4. #4
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    I think your problem is that you don't understand what scanf returns. Here's what a good reference has to say:
    Quote Originally Posted by man 3 scanf
    These functions return the number of input items successfully matched and assigned, which can be fewer than provided for, or even zero in the event of an early matching failure.

    The value EOF is returned if the end of input is reached before either the first successful conversion or a matching failure occurs. EOF is also returned if a read error occurs, in which case the error indicator for the stream (see ferror(3)) is set, and errno is set indicate the error.
    Rather than EOF, which as far as I can tell is only returned when the file is broken or empty, it is safer to compare against something else:
    Code:
    while ( scanf( "%d", &userid ) != 1 ) {
        /* get rid of garbage from bad scan */
    }
    Since 1 will be returned when this succeeds and we want to keep trying when it's not that.

  5. #5
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    Quote Originally Posted by littlerunaway View Post
    that's why I got an infinite loop. I see. I can't really use those methods to get rid of the unwanted data cuz they don't really let us use things we haven't learnt in class yet.

    I actually wrote first the program using the getchar() function which worked better but turned out to be longer.
    It seems you missed the essential line in the link I gave you:
    Code:
    while ((ch = getchar()) != '\n' && ch != EOF);
    This line reads the current character from the input stream and checks whether it is '\n' or EOF. If it is not, the character is thrown away and the loop continues. At the end all characters up to the next newline (inclusive) or EOF are thrown away.
    Since you know about while, getchar() and EOF, I don't see a reason why you aren't able to use it.

    Quote Originally Posted by littlerunaway View Post
    anyway, another question.
    in my current program when I press the "enter" after some input it starts the execution of the program. is there a way to make it so that "enter" will simply request more input on the next line and execution starts only after CTRL+z (EOF)?
    meaning if I want to input the ID numbers with an "enter" between them rather than on the same line (I hope I'm being clear, English is not my first language).
    Sorry, I don't understand. Can you provide a sample session and your code?

    Bye, Andreas

  6. #6
    Registered User
    Join Date
    Dec 2012
    Posts
    10
    "scanf(%d) stops at the first character which isn't a number and leaves that character (in your example 'a') in the input stream.
    Thus if you try to use scanf(%d) another time (at your next iteration) it will still stop at that character and will never move on."
    that's my problem. incase there's an error like 12a34, I need to continue to the other numbers and I don't know how to "
    get rid of garbage from bad scan"


  7. #7
    Registered User
    Join Date
    Dec 2012
    Posts
    10
    so if scanf fails because of a character, I can get rid of that character with getchar()? did I understand correctly?
    so if I have 12a34, scanf fails with the 'a', getchar() takes it away, the next scanf will continue reading from where? from 3 or after the space?

    you have to bear with me here, I'm not an expert, just started learning this in class 2 months ago.

  8. #8
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    Quote Originally Posted by littlerunaway View Post
    so if scanf fails because of a character, I can get rid of that character with getchar()? did I understand correctly?
    so if I have 12a34, scanf fails with the 'a', getchar() takes it away, the next scanf will continue reading from where? from 3 or after the space?
    If you call getchar() once, the next scanf() will start at '3'.

    So the question is: Is "12a34" a complete failure (meaning you throw it away completely) or you just want to get rid of the 'a' and "1234" would be valid?

    Bye, Andreas

  9. #9
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Quote Originally Posted by littlerunaway View Post
    that's my problem. incase there's an error like 12a34, I need to continue to the other numbers and I don't know how to "[/COLOR]get rid of garbage from bad scan"

    Well you were given the code to ignore garbage from bad scan in post #5.

    I will try to explain how scanf will work with the input "12a34".
    This is the code:
    scanf("%d", &userid);
    You will get
    userid = 12
    and the scanning stopped at 'a'. So %d by itself is not enough.

    You could do something like:
    scanf("%d%c", &userid, &maybeEnter);
    So with the input "12a34", you would get:
    userid = 12
    maybeEnter = 'a'
    Since 'a' is not the enter key ('\n') you need to reject this, get rid of the garbage from the bad scan, and keep trying. So you have to check 2 things in the new loop condition: check what scanf returned, and what was entered after the user id.

    Any questions?

  10. #10
    Registered User
    Join Date
    Dec 2012
    Posts
    10
    yeah, 12a34 is a complete failure, I need to print an error, trow the whole thing away and check the next number.

  11. #11
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    You should have enough information and code to try this again, by now.

  12. #12
    Registered User
    Join Date
    Dec 2012
    Posts
    10
    working on it. it doesn't come to me as easy as you may think.

  13. #13
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    That's understandable. Before you start writing the code, conceptualize the idea - plan out step by step how you will read in the input, check for valid data, and if the data is invalid, how you will inform the user and clear the input buffer. Then use this as a reference to write your code.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. scanf and EOF
    By Satya in forum C Programming
    Replies: 3
    Last Post: 03-05-2012, 11:26 AM
  2. scanf
    By mnml in forum C Programming
    Replies: 9
    Last Post: 11-19-2011, 07:52 PM
  3. scanf
    By Tool in forum C Programming
    Replies: 4
    Last Post: 02-23-2010, 03:21 AM
  4. First scanf() skips next scanf() !
    By grahampatten in forum C Programming
    Replies: 5
    Last Post: 08-17-2004, 02:47 AM
  5. scanf - data is "put back" - screws up next scanf
    By voltson in forum C Programming
    Replies: 10
    Last Post: 10-14-2002, 04:34 AM