Parsing a simple string

Discussion in 'C Programming' started by mathieu, May 9, 2006.

  1. mathieu

    mathieu Guest

    Hello,

    I am trying to parse a string and I am surprised by the result(*)
    When using:
    sscanf(s, "%03u%c", &val, &f);
    If a number less than 3 digits is found, shouldn't sscanf report
    that ?

    Thanks
    Mathieu


    (*)
    #include <stdio.h>

    void parse(const char *s)
    {
    unsigned int val;
    char f;
    int k = sscanf(s, "%03u%c", &val, &f);
    printf( "%d %u %c\n", k, val, f);
    }

    int main()
    {
    // 21 years:
    parse( "021Y" );
    // -1 year (invalid)
    parse( "0-1Y" );

    return 0;
    }
    mathieu, May 9, 2006
    #1
    1. Advertising

  2. mathieu wrote:
    > Hello,
    >
    > I am trying to parse a string and I am surprised by the result(*)
    > When using:
    > sscanf(s, "%03u%c", &val, &f);
    > If a number less than 3 digits is found, shouldn't sscanf report
    > that ?


    scanf conversion specifiers are not the same as printf's. The %03u
    obviously doesn't do what you think it does. The 0 is superfluous and
    the 3 just indicates that the *maximum* number of characters to be read
    (after skipping any leading whitespace) for that conversion is 3.
    Check your documentation for details.

    Robert Gamble
    Robert Gamble, May 9, 2006
    #2
    1. Advertising

  3. mathieu

    mathieu Guest

    Oooops I missed the 'maximum'. Thanks for the info.
    I guess I simply make sure that all of the three first char are
    decimal.

    Mathieu
    mathieu, May 9, 2006
    #3
  4. mathieu

    mathieu Guest

    Just for ref. Here is the final solution:

    void parse(const char *s)
    {
    unsigned int val;
    char f;
    if( !isdigit(s[0])
    || !isdigit(s[1])
    || !isdigit(s[2]))
    {
    printf( "error\n");
    }
    else
    {
    int k = sscanf(s, "%03u%c", &val, &f);
    printf( "%d %u %c\n", k, val, f);
    }
    }
    mathieu, May 9, 2006
    #4
  5. mathieu

    Eric Sosman Guest

    mathieu wrote On 05/09/06 16:03,:
    > Just for ref. Here is the final solution:
    >
    > void parse(const char *s)
    > {
    > unsigned int val;
    > char f;
    > if( !isdigit(s[0])
    > || !isdigit(s[1])
    > || !isdigit(s[2]))
    > {
    > printf( "error\n");
    > }
    > else
    > {
    > int k = sscanf(s, "%03u%c", &val, &f);
    > printf( "%d %u %c\n", k, val, f);
    > }
    > }


    Just for reference, the above code still has an
    error that can cause trouble on some systems. The
    problem is that `char' can be a signed type or an
    unsigned type, whichever the implementation finds
    more convenient. On systems where `char' is signed,
    it could happen that any or all of s[0] through s[2]
    might have negative values. However, isdigit() only
    works on non-negative `char' values and on the negative
    value EOF; feed it some other negative value, and
    unpredictable things will happen. (True, the digits
    are known to have positive values -- but if you knew in
    advance that you were dealing with digits, you wouldn't
    need the isdigit() calls in the first place!)

    Fortunately, the cure (for isdigit() and for the
    rest of the <ctype.h> functions) is simple: When you
    apply one of them to a `char' value, just convert the
    `char' to the corresponding non-negative value:

    if ( !isdigit( (unsigned char)s[0] ) ...

    Note the part about applying the functions to a
    `char'. If you apply them to the `int' value returned
    by getchar() or getc() or fgetc(), you should not convert
    as shown: the value is already either a converted non-
    negative character or else it is the negative number EOF.
    If it is EOF, you don't want to convert it from negative
    to positive; you want to leave it alone. And if it's not
    EOF, it's already non-negative and needs no conversion.
    But when you're plucking character values from a string
    or something, you need the sign conversion.

    --
    Eric Sosman, May 9, 2006
    #5
  6. mathieu

    Guest

    mathieu wrote:
    > Just for ref. Here is the final solution:
    >
    > void parse(const char *s)
    > {
    > unsigned int val;
    > char f;
    > if( !isdigit(s[0])
    > || !isdigit(s[1])
    > || !isdigit(s[2]))
    > {
    > printf( "error\n");
    > }
    > else
    > {
    > int k = sscanf(s, "%03u%c", &val, &f);
    > printf( "%d %u %c\n", k, val, f);
    > }
    > }


    With a sscanf format of "%u", leading white space in the input
    string, if present, is skipped during conversion. You may want to
    consider the possibility of white space being in your input string.
    In such a case, a function like this may be useful:

    #include <string.h>

    size_t count_digits_after_ws (const char *s)
    {
    const char *ptr = s;
    size_t offset = strspn(ptr, " \n\t\r\f\v");
    ptr += offset;
    offset = strspn(ptr, "0123456789");
    return offset;
    }

    --
    Hope this helps,
    Steven
    , May 10, 2006
    #6
  7. mathieu

    mathieu Guest

    In this case I am better of with something like:

    if( '0' > s[0] || s[0] > '9' )
    mathieu, May 10, 2006
    #7
  8. mathieu wrote:
    > In this case I am better of with something like:
    >
    > if( '0' > s[0] || s[0] > '9' )
    >

    Check line 42. There is an error there for sure.
    void * clvrmnky(), May 10, 2006
    #8
  9. mathieu

    mathieu Guest

    I am saying that:

    if( s[0] < '0' || s[0] > '9'
    || s[1] < '0' || s[1] > '9'
    || s[2] < '0' || s[2] > '9' )
    {

    is equivalent to my previous post with the call of isdigit. But as far
    as understand it should not suffer from the unsigned char cast, right ?
    mathieu, May 10, 2006
    #9
  10. "mathieu" <> writes:
    > I am saying that:
    >
    > if( s[0] < '0' || s[0] > '9'
    > || s[1] < '0' || s[1] > '9'
    > || s[2] < '0' || s[2] > '9' )
    > {
    >
    > is equivalent to my previous post with the call of isdigit. But as far
    > as understand it should not suffer from the unsigned char cast, right ?


    I have no idea, since you didn't include any information from your
    previous post.

    Read <http://cfaj.freeshell.org/google/>.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
    Keith Thompson, May 10, 2006
    #10
  11. mathieu

    pete Guest

    mathieu wrote:
    >
    > I am saying that:
    >
    > if( s[0] < '0' || s[0] > '9'
    > || s[1] < '0' || s[1] > '9'
    > || s[2] < '0' || s[2] > '9' )
    > {
    >
    > is equivalent to my previous post with the call of isdigit. But as far
    > as understand it should not suffer from the unsigned char cast,
    > right ?


    Right.

    --
    pete
    pete, May 10, 2006
    #11
  12. mathieu

    Richard Bos Guest

    "mathieu" <> brokenly-Google-Grouped:

    > I am saying that:
    >
    > if( s[0] < '0' || s[0] > '9'
    > || s[1] < '0' || s[1] > '9'
    > || s[2] < '0' || s[2] > '9' )
    > {
    >
    > is equivalent to my previous post with the call of isdigit. But as far
    > as understand it should not suffer from the unsigned char cast, right ?


    There is no unsigned char cast in that code, so no, it doesn't suffer
    from any unsigned char casts.

    Richard
    Richard Bos, May 11, 2006
    #12
  13. mathieu

    mathieu Guest

    mathieu, May 11, 2006
    #13
  14. mathieu

    Flash Gordon Guest

    mathieu wrote:
    > Sorry for that.


    Sorry for what? Provide context please when quoting. There are links at
    http://clc-wiki.net/wiki/Intro_to_clc to sites with instructions.

    > I'll keep that in mind. I did vote for the feature
    > request at:
    >
    > http://groups-beta.google.com/support/bin/request.py?contact_type=features


    Vote for which feature? Google being separated from Usenet so we don't
    get all these context-less posts?
    --
    Flash Gordon, living in interesting times.
    Web site - http://home.flash-gordon.me.uk/
    comp.lang.c posting guidelines and intro:
    http://clc-wiki.net/wiki/Intro_to_clc

    Inviato da X-Privat.Org - Registrazione gratuita http://www.x-privat.org/join.php
    Flash Gordon, May 11, 2006
    #14
  15. mathieu

    mathieu Guest

    > Vote for which feature? Google being separated from Usenet so we don't
    > get all these context-less posts?


    Ok I said, I apologized.
    What do you do when you only have read access to the newsgroups,
    google.groups is very convenient solution, not perfect yet, that's all.
    mathieu, May 11, 2006
    #15
  16. "mathieu" <> writes:
    > Sorry for that. I'll keep that in mind. I did vote for the feature
    > request at:
    >
    > http://groups-beta.google.com/support/bin/request.py?contact_type=features


    I *think* you're saying you voted for the "Default quoting of previous
    message in replies" feature. Thanks for that, but it's ironic that
    you mention this while not using the simple workaround that lets you
    do this in spite of Google's broken interface. (And in a later
    followup in this thread, you quote a previous article but snip the
    attribution line.)

    You *have* read <http://cfaj.freeshell.org/google/>, right?

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
    Keith Thompson, May 11, 2006
    #16
  17. mathieu

    SM Ryan Guest

    And incessant whining about Google has what to do with
    the programming language C?


    Flash Gordon <> wrote:
    # mathieu wrote:
    # > Sorry for that.
    #
    # Sorry for what? Provide context please when quoting. There are links at
    # http://clc-wiki.net/wiki/Intro_to_clc to sites with instructions.
    #
    # > I'll keep that in mind. I did vote for the feature
    # > request at:
    # >
    # > http://groups-beta.google.com/support/bin/request.py?contact_type=features
    #
    # Vote for which feature? Google being separated from Usenet so we don't
    # get all these context-less posts?
    # --
    # Flash Gordon, living in interesting times.
    # Web site - http://home.flash-gordon.me.uk/
    # comp.lang.c posting guidelines and intro:
    # http://clc-wiki.net/wiki/Intro_to_clc
    #
    # Inviato da X-Privat.Org - Registrazione gratuita http://www.x-privat.org/join.php
    #
    #

    --
    SM Ryan http://www.rawbw.com/~wyrmwif/
    Mention something out of a Charleton Heston movie, and suddenly
    everybody's a theology scholar.
    SM Ryan, May 13, 2006
    #17
  18. SM Ryan <> writes:
    > And incessant whining about Google has what to do with
    > the programming language C?


    It makes it possible to discuss it coherently.

    I see you've decided to start top-posting. I can't say I'm surprised.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
    Keith Thompson, May 13, 2006
    #18
  19. mathieu

    Default User Guest

    Keith Thompson wrote:

    > SM Ryan <> writes:
    > > And incessant whining about Google has what to do with
    > > the programming language C?

    >
    > It makes it possible to discuss it coherently.
    >
    > I see you've decided to start top-posting. I can't say I'm surprised.


    Trolls tend to degenerate as their current bag o' tricks gets stale. I
    killfiled him long ago over past antics.



    Brian
    Default User, May 13, 2006
    #19
  20. mathieu

    mathieu Guest

    Keith Thompson wrote:
    > I *think* you're saying you voted for the "Default quoting of previous
    > message in replies" feature. Thanks for that, but it's ironic that
    > you mention this while not using the simple workaround that lets you
    > do this in spite of Google's broken interface. (And in a later
    > followup in this thread, you quote a previous article but snip the
    > attribution line.)


    I'll make sure to keep attribution line, too. Thx

    -M
    mathieu, May 17, 2006
    #20
    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. GIMME
    Replies:
    2
    Views:
    857
    GIMME
    Feb 11, 2004
  2. TAG

    simple string parsing ?

    TAG, Sep 9, 2004, in forum: Python
    Replies:
    8
    Views:
    396
    Alex Martelli
    Sep 10, 2004
  3. TAG

    Re: simple string parsing ?

    TAG, Sep 9, 2004, in forum: Python
    Replies:
    1
    Views:
    321
    Peter Abel
    Sep 9, 2004
  4. Marc E
    Replies:
    2
    Views:
    282
  5. ankur
    Replies:
    1
    Views:
    12,665
    Jan =?UTF-8?B?VGhvbcOk?=
    Aug 27, 2007
Loading...

Share This Page