scanf and sscanf

Discussion in 'C Programming' started by Bill Cunningham, Jul 8, 2013.

  1. What would be a practical reason to use sscanf? I read an example of how
    it works but I can pretty much use scanf to do the same thing.

    B
     
    Bill Cunningham, Jul 8, 2013
    #1
    1. Advertising

  2. Bill Cunningham wrote:
    > What would be a practical reason to use sscanf? I read an example
    > of how it works but I can pretty much use scanf to do the same thing.
    >
    > B


    Also the FAQ 12.20 answer ¶3 or so says use fgets and then sscanf. BTW
    What's it mean by scanf's big %s problem? Is the %s the same with any other
    specifiers?

    B
     
    Bill Cunningham, Jul 8, 2013
    #2
    1. Advertising

  3. Bill Cunningham <> wrote:

    > What would be a practical reason to use sscanf?


    I use it for converting strings to numbers, such as for numeric
    arguments.

    -- glen
     
    glen herrmannsfeldt, Jul 8, 2013
    #3
  4. glen herrmannsfeldt wrote:

    > I use it for converting strings to numbers, such as for numeric
    > arguments.


    Really. Can you show me an example? I would use functions from string.h
    to do that like strtol or atoi strtoul and so on.

    B
     
    Bill Cunningham, Jul 8, 2013
    #4
  5. Bill Cunningham <> wrote:
    > glen herrmannsfeldt wrote:


    >> I use it for converting strings to numbers, such as for numeric
    >> arguments.


    > Really. Can you show me an example? I would use functions
    > from string.h to do that like strtol or atoi strtoul and so on.


    I usually use sscanf() instead, but yes you could do that.

    sscanf(argv[1],"%d",&n);

    with the usual int main(int argc, char **argv).

    -- glen
     
    glen herrmannsfeldt, Jul 8, 2013
    #5
  6. "Bill Cunningham" <> writes:

    > glen herrmannsfeldt wrote:
    >
    >> I use it for converting strings to numbers, such as for numeric
    >> arguments.

    >
    > Really. Can you show me an example? I would use functions from string.h
    > to do that like strtol or atoi strtoul and so on.


    sscanf has primitive pattern matching, which is useful for simple cases,
    e.g.,

    n = sscanf(somestring,"(%d,%d)",&x,&y);

    (scanf has the same capabilities I think; I never use it).

    I don't know whether this is standard, though.

    -- Alain.
     
    Alain Ketterlin, Jul 8, 2013
    #6
  7. On Sun, 7 Jul 2013 22:03:14 -0400, "Bill Cunningham"
    <> wrote:

    >Bill Cunningham wrote:
    >> What would be a practical reason to use sscanf? I read an example
    >> of how it works but I can pretty much use scanf to do the same thing.


    scanf extracts data from the stdin stream. sscanf extracts data form
    a string. Both functions ignore leading white space characters when
    extracting strings or numbers. Thus it is possible that scanf will
    silently skip to the next line. If you don't want this to happen, you
    use fgets to read an entire line and sscanf to process the data. The
    string produced by fgets will never contain more than one line of data
    from the file or stream.

    There are also times when you may want to process the data multiple
    times, possibly with different conversion specifications. Once scanf
    has read the data, it is no longer in the stream so you cannot
    reprocess it. On the other hand, sscanf does not destroy the data in
    the string so you can process it repeatedly if needed.

    >Also the FAQ 12.20 answer ¶3 or so says use fgets and then sscanf. BTW
    >What's it mean by scanf's big %s problem? Is the %s the same with any other
    >specifiers?


    With either scanf or sscanf, the %s format will not extract a string
    with embedded spaces or other white space characters. Thus %s can not
    be used to read a name like John Doe. Both functions would stop at
    the space and extract the string John. If you use fgets, you could
    then use strncpy or a similar function to extract both the first and
    last names to a single string.

    The problem does not exist with other specifiers since you cannot have
    embedded white space in a number and %c does not treat white space as
    special.

    --
    Remove del for email
     
    Barry Schwarz, Jul 8, 2013
    #7
  8. Bill Cunningham

    Noob Guest

    Noob, Jul 8, 2013
    #8
  9. Bill Cunningham

    Nobody Guest

    On Sun, 07 Jul 2013 22:03:14 -0400, Bill Cunningham wrote:

    > Bill Cunningham wrote:
    >> What would be a practical reason to use sscanf? I read an example
    >> of how it works but I can pretty much use scanf to do the same thing.
    >>
    >> B

    >
    > Also the FAQ 12.20 answer ¶3 or so says use fgets and then sscanf.


    fgets()+sscanf() is appropriate when newlines are significant, i.e. each
    "chunk" of input is on its own line. If the input contains too few values,
    fgets()+sscanf() will parse one line of input and tell you how many
    values it obtained, whereas fscanf() will start reading values from the
    next line().

    fscanf() is appropriate when newlines are merely whitespace (e.g. as is
    the case for C source code).

    > BTW What's it mean by scanf's big %s problem? Is the %s the same with
    > any other specifiers?


    I presume that it refers to the fact that "%s" will copy an arbitrary
    number of characters into the buffer pointed to by the corresponding
    argument. If the number of characters exceeds the size of the buffer, you
    get an overflow.

    Note that %[ has the same issue.
     
    Nobody, Jul 8, 2013
    #9
  10. Bill Cunningham

    James Kuyper Guest

    On 07/08/2013 03:29 AM, Alain Ketterlin wrote:
    ....
    > sscanf has primitive pattern matching, which is useful for simple cases,
    > e.g.,
    >
    > n = sscanf(somestring,"(%d,%d)",&x,&y);
    >
    > (scanf has the same capabilities I think; I never use it).


    "The sscanf function is equivalent to fscanf, except that input is
    obtained from a string (specified by the argument s) rather than from a
    stream." 7.21.6.7p2.

    Note that if the input string represents a number too large to be stored
    in an 'int', the behavior is undefined (7.21.6.2p10). This is a problem
    that can be avoided by using strtol() instead; but at the cost of using
    a more complicated interface.

    > I don't know whether this is standard, though.


    Very much so.
    --
    James Kuyper
     
    James Kuyper, Jul 8, 2013
    #10
  11. Barry Schwarz wrote:
    > On Sun, 7 Jul 2013 22:03:14 -0400, "Bill Cunningham"
    > <> wrote:
    >
    >> Bill Cunningham wrote:
    >>> What would be a practical reason to use sscanf? I read an example
    >>> of how it works but I can pretty much use scanf to do the same
    >>> thing.

    >
    > scanf extracts data from the stdin stream. sscanf extracts data form
    > a string. Both functions ignore leading white space characters when
    > extracting strings or numbers. Thus it is possible that scanf will
    > silently skip to the next line. If you don't want this to happen, you
    > use fgets to read an entire line and sscanf to process the data. The
    > string produced by fgets will never contain more than one line of data
    > from the file or stream.
    >
    > There are also times when you may want to process the data multiple
    > times, possibly with different conversion specifications. Once scanf
    > has read the data, it is no longer in the stream so you cannot
    > reprocess it. On the other hand, sscanf does not destroy the data in
    > the string so you can process it repeatedly if needed.
    >
    >> Also the FAQ 12.20 answer ¶3 or so says use fgets and then sscanf.
    >> BTW What's it mean by scanf's big %s problem? Is the %s the same
    >> with any other specifiers?

    >
    > With either scanf or sscanf, the %s format will not extract a string
    > with embedded spaces or other white space characters. Thus %s can not
    > be used to read a name like John Doe. Both functions would stop at
    > the space and extract the string John. If you use fgets, you could
    > then use strncpy or a similar function to extract both the first and
    > last names to a single string.
    >
    > The problem does not exist with other specifiers since you cannot have
    > embedded white space in a number and %c does not treat white space as
    > special.


    Thanks much. That answers my question.
     
    Bill Cunningham, Jul 8, 2013
    #11
  12. Bill Cunningham

    James Kuyper Guest

    On 07/08/2013 05:12 AM, Nobody wrote:
    ....
    > fgets()+sscanf() is appropriate when newlines are significant, i.e. each
    > "chunk" of input is on its own line. If the input contains too few values,
    > fgets()+sscanf() will parse one line of input and tell you how many
    > values it obtained, whereas fscanf() will start reading values from the
    > next line().
    >
    > fscanf() is appropriate when newlines are merely whitespace ...


    True

    > ... (e.g. as is
    > the case for C source code).


    Not true. In phase 7, "White-space characters separating tokens are no
    longer significant", which renders new-line characters outside of tokens
    insignificant (new-line characters can occur inside of character
    constant and string literal tokens as a result of translation of \n
    escape sequences during phase 6). However, many features of C which are
    implemented prior to phase 7 depend upon correctly distinguishing
    between new-line characters and other white-space characters:

    Phase 2: "Each instance of a backslash character (\) immediately
    followed by a new-line character is deleted, splicing physical source
    lines to form logical source lines."

    Phase 3:
    * It is a syntax error for a header name, character constant, or string
    literal to contain a new-line character.

    Phase 4:
    * The # character that distinguishes pre-processing directives must be
    the first non-whitespace character after a new-line character or the
    start of the source code file.
    * Preprocessing directives are terminated by new-line characters - even
    if doing so would interrupt what would otherwise be the invocation of a
    function-like macro.
    * __LINE__ must expand into 1 more than then number of new-line
    characters were read during translation phase 1 at the point where that
    token is parsed.
    * assert(condition) must expand into code which, if condition is false,
    causes (among other things) the line number to be printed out. The most
    obvious way to do this is by use of __LINE__, though that's not required.

    ....
    > I presume that it refers to the fact that "%s" will copy an arbitrary
    > number of characters into the buffer pointed to by the corresponding
    > argument. If the number of characters exceeds the size of the buffer, you
    > get an overflow.
    >
    > Note that %[ has the same issue.


    Buffer overflow can be avoided by specification of a maximum field
    width: "%32s". This is even mentioned in a footnote to the FAQ
    <http://www.c-faq.com/stdio/overflow.html>
    --
    James Kuyper
     
    James Kuyper, Jul 8, 2013
    #12
  13. Bill Cunningham

    John Gordon Guest

    In <EkoCt.20717$> "Bill Cunningham" <> writes:

    > What would be a practical reason to use sscanf? I read an example of how
    > it works but I can pretty much use scanf to do the same thing.


    scanf consumes its input directly from the input stream. Once scanf reads
    something, it's gone; you can't go back and read it again.

    --
    John Gordon A is for Amy, who fell down the stairs
    B is for Basil, assaulted by bears
    -- Edward Gorey, "The Gashlycrumb Tinies"
     
    John Gordon, Jul 8, 2013
    #13
  14. Bill Cunningham

    Ken Brody Guest

    On 7/8/2013 11:17 AM, John Gordon wrote:
    > In <EkoCt.20717$> "Bill Cunningham" <> writes:
    >
    >> What would be a practical reason to use sscanf? I read an example of how
    >> it works but I can pretty much use scanf to do the same thing.

    >
    > scanf consumes its input directly from the input stream. Once scanf reads
    > something, it's gone; you can't go back and read it again.


    And, IIRC, if it encounters an error, scanf() leaves the rest of the line in
    the input stream, possibly leading to other problems.
     
    Ken Brody, Jul 8, 2013
    #14
  15. David Harmon <> writes:
    > On Sun, 7 Jul 2013 22:03:14 -0400 in comp.lang.c, "Bill Cunningham"
    > <> wrote,
    >>What's it mean by scanf's big %s problem? Is the %s the same with any other
    >>specifiers?

    >
    > The problem is that people forget that the length specification is
    > *essential* to using %s safely.


    sscanf can be used safely with "%s", if you exercise caerful control
    over the string being scanned. Such control is (usually) not possible
    for scanf, which reads from stdin.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Working, but not speaking, for JetHead Development, Inc.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jul 9, 2013
    #15
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Rob Thorpe

    Correct behaviour of scanf and sscanf

    Rob Thorpe, Mar 14, 2005, in forum: C Programming
    Replies:
    6
    Views:
    452
    Dan Pop
    Mar 15, 2005
  2. effbiae

    sscanf and scanf behave differently

    effbiae, Jan 19, 2006, in forum: C Programming
    Replies:
    2
    Views:
    354
    Keith Thompson
    Jan 19, 2006
  3. =?ISO-8859-1?Q?Martin_J=F8rgensen?=

    difference between scanf("%i") and scanf("%d") ??? perhaps bug inVS2005?

    =?ISO-8859-1?Q?Martin_J=F8rgensen?=, Apr 26, 2006, in forum: C Programming
    Replies:
    18
    Views:
    680
    Richard Bos
    May 2, 2006
  4. ryniek90
    Replies:
    15
    Views:
    1,433
  5. ryniek90
    Replies:
    0
    Views:
    244
    ryniek90
    Oct 13, 2009
Loading...

Share This Page