Character literals in scanf

This is a discussion on Character literals in scanf within the C Programming forums, part of the General Programming Boards category; 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", ...

  1. #1
    DL1
    DL1 is offline
    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 wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,544
    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.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  3. #3
    DL1
    DL1 is offline
    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 wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,544
    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.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  5. #5
    CSharpener vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,484
    also checking the return value of scanf will prevent you from printing garbage when only one or none of the arrays is filled
    The first 90% of a project takes 90% of the time,
    the last 10% takes the other 90% of the time.

  6. #6
    DL1
    DL1 is offline
    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 wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,544
    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.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  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
    DL1
    DL1 is offline
    Registered User
    Join Date
    Jun 2008
    Location
    Somewhere in Europe
    Posts
    99
    OK. Thanks again. I will have to think about that!

  10. #10
    DL1
    DL1 is offline
    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,185
    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
    DL1
    DL1 is offline
    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, 07: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, 06:23 PM

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