Thread: Character literals in scanf

  1. #1
    Registered User
    Join Date
    Jun 2008
    Location
    Somewhere in Europe
    Posts
    99

    Character literals in scanf

    Hello again,

    Yet another beginner question...

    Code:
    #include <stdio.h>
    
    int main()
    {
     char i[20], j[20];
    
     scanf("%s/%s", i, j);
    
     printf("%s %s", i, j);
     return 0;
    }
    I'm sure you wouldn't ever use scanf like this in practive, but I stuck the "/" in just to see what would happen. When I ran the program, I entered "hello / world". I expected that:

    1. "hello" would be stored in i,
    2. the "/" would be ignored, since it is identical to the "/" in the format string,
    3. "world" would be stored in j,

    so the output should be "hello world".

    However this isn't the case. All that is output is "hello" followed by a white space and four unrecognisable characters.

    If I type in "xyz" followed by enter, the program outputs "xyz" followed by the same unrecognisable characters. That I really don't understand, since scanf has surely only read in one string at this point and should be expecting more input - it beats me why the program should pass beyond scanf at all.

    Any suggestions as to what I am overlooking would be most appreciated. Incidentally, I am using Code::Blocks.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Add a space either side of the / in the scanf call.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Jun 2008
    Location
    Somewhere in Europe
    Posts
    99
    Thanks. In fact, just adding a space before the "/" seems to be adequate.

    The question now is why didn't it work without the space?

    I presume scanf was comparing the white space immediately after the first input string ("hello") with the "/" in its format string, finding they didn't match, and hence returning control to main(). Is that correct?

    According to K&R, blanks and tabs are ignored in the format string. It looks as though that is isn't the case here. Also, the statement in K&R that scanf "skips over white space ... as it looks for input values" would seem also to be not entirely true if my analysis above is correct.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    A single space in a format string matches any sequence of spaces, tabs, newlines (or anything else where isspace() would be true) on the input.

    If you typed in "hello/world", then you'd need a different scanf call. In particular, %s uses whitespace as a delimiter, so you need something to stop the first %s grabbing the whole word.
    In this case, the format would be "%[^/]/%s"
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    also checking the return value of scanf will prevent you from printing garbage when only one or none of the arrays is filled
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  6. #6
    Registered User
    Join Date
    Jun 2008
    Location
    Somewhere in Europe
    Posts
    99
    A single space in a format string matches any sequence of spaces, tabs, newlines (or anything else where isspace() would be true) on the input.

    Is that laid down explicitly in the standard (I haven't been able to find it in K&R - or maybe I have but just haven't properly understood the implications), or is it just a logical consequence of the way scanf deals with %s?

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Quote Originally Posted by c99
    5 A directive composed of white-space character(s) is executed by reading input up to the
    first non-white-space character (which remains unread), or until no more characters can
    be read.
    You can have more than one white-space in your format string, but it doesn't change the meaning.

    You can't for example have say
    Code:
    "%d   %d"
    and explicitly match 3 spaces between two integers.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  8. #8
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    C99:
    5 A directive composed of white-space character(s) is executed by reading input up to the
    first non-white-space character (which remains unread), or until no more characters can
    be read.

  9. #9
    Registered User
    Join Date
    Jun 2008
    Location
    Somewhere in Europe
    Posts
    99
    OK. Thanks again. I will have to think about that!

  10. #10
    Registered User
    Join Date
    Jun 2008
    Location
    Somewhere in Europe
    Posts
    99
    K&R state on page 245 that "The format string may contain: Blanks or tabs, which are ignored. ..."

    That would seem to conflict with the standard.

  11. #11
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by DL1 View Post
    K&R state on page 245 that "The format string may contain: Blanks or tabs, which are ignored. ..."

    That would seem to conflict with the standard.
    From the errata to the book on Dennis Ritchie's home page:
    245(§B1.3, and also at p. 157 §7.4): The scanf functions do not ignore white space in formats; if white space occurs at a place in the format, any white space in the corresponding input is skipped.
    Always a good idea to go through errata when you can.

  12. #12
    Registered User
    Join Date
    Jun 2008
    Location
    Somewhere in Europe
    Posts
    99
    Indeed. Thanks for the tip - I didn't know that an errata had been published.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Using a character array in a switch question.
    By bajanElf in forum C Programming
    Replies: 10
    Last Post: 11-08-2008, 08:06 AM
  2. Replies: 11
    Last Post: 10-07-2008, 06:19 PM
  3. about wide character and multiple byte character
    By George2 in forum C Programming
    Replies: 3
    Last Post: 05-22-2006, 08:11 PM
  4. Please Help - Problem with Compilers
    By toonlover in forum C++ Programming
    Replies: 5
    Last Post: 07-23-2005, 10:03 AM
  5. mygets
    By Dave_Sinkula in forum C Programming
    Replies: 6
    Last Post: 03-23-2003, 07:23 PM