Testing for Numeric Digits

Discussion in 'C++' started by Mike Copeland, Feb 26, 2012.

  1. Is there a relatively easy and simple way to determine if a
    basic::string value is comprised only of numeric digits? I have an
    application that parses a comma-delimited string, and I want to test if
    specific values are strictly numeric. It was working until I got a
    mixed alphanumeric value that started with a numeric digit (e.g.
    "6btt123"), which caused the following code to fail:

    int ii = atoi(wStr.c_str());
    if(ii) // numeric processing
    {
    // expecting purely numeric value in "ii"
    [etc.]
    }
    else // alphanumeric processing
    {
    // process alphanumeric data
    }
    when it fell into the numeric processing branch.
    I know that I could examine the contents of the "wStr" string
    character-by-character to test if each character is a digit character,
    but that seems slow and inefficient. Is there a better way to do such
    processing? Thoughts? TIA
     
    Mike Copeland, Feb 26, 2012
    #1
    1. Advertising

  2. Mike Copeland

    Ian Collins Guest

    On 02/27/12 11:05 AM, Mike Copeland wrote:
    > Is there a relatively easy and simple way to determine if a
    > basic::string value is comprised only of numeric digits? I have an
    > application that parses a comma-delimited string, and I want to test if
    > specific values are strictly numeric. It was working until I got a
    > mixed alphanumeric value that started with a numeric digit (e.g.
    > "6btt123"), which caused the following code to fail:
    >
    > int ii = atoi(wStr.c_str());


    Never use atoi(), it has now way to indicate failure. Use strtol() and
    check errno.


    > if(ii) // numeric processing
    > {
    > // expecting purely numeric value in "ii"
    > [etc.]
    > }
    > else // alphanumeric processing
    > {
    > // process alphanumeric data
    > }
    > when it fell into the numeric processing branch.
    > I know that I could examine the contents of the "wStr" string
    > character-by-character to test if each character is a digit character,
    > but that seems slow and inefficient. Is there a better way to do such
    > processing? Thoughts? TIA


    What are you reading form? iterating a sting is orders of magnitude
    faster than reading from a file.

    --
    Ian Collins
     
    Ian Collins, Feb 26, 2012
    #2
    1. Advertising

  3. Mike Copeland

    Ian Collins Guest

    On 02/27/12 11:11 AM, Ian Collins wrote:
    >
    > Never use atoi(), it has now way to indicate failure. Use strtol() and
    > check errno.


    Usual Monday morning keyboard issues: "no way to indicate failure.".

    --
    Ian Collins
     
    Ian Collins, Feb 26, 2012
    #3
  4. Mike Copeland

    Paul Guest

    On Feb 26, 10:22 pm, Ian Collins <> wrote:
    > On 02/27/12 11:11 AM, Ian Collins wrote:
    >
    >
    >
    > > Never use atoi(), it has now way to indicate failure.  Use strtol() and
    > > check errno.

    >
    > Usual Monday morning keyboard issues: "no way to indicate failure.".
    >
    > --
    > Ian Collins


    Whatabout isdigit?
     
    Paul, Feb 27, 2012
    #4
  5. Mike Copeland

    Miles Bader Guest

    (Mike Copeland) writes:
    > I know that I could examine the contents of the "wStr" string
    > character-by-character to test if each character is a digit character,
    > but that seems slow and inefficient. Is there a better way to do such
    > processing? Thoughts? TIA


    if (wStr.find_first_not_of ("0123456789") == string::npos)
    => All chars are digits

    [Most efficient? I dunno. But reasonably concise...]

    -miles

    --
    Alone, adj. In bad company.
     
    Miles Bader, Feb 27, 2012
    #5
  6. Mike Copeland

    Stefan Ram Guest

    (Mike Copeland) writes:
    >I know that I could examine the contents of the "wStr" string
    >character-by-character to test if each character is a digit character,
    >but that seems slow and inefficient.


    How do you think »atoi« does it?
     
    Stefan Ram, Feb 27, 2012
    #6
  7. Mike Copeland

    Dombo Guest

    Op 26-Feb-12 23:05, Mike Copeland schreef:
    > Is there a relatively easy and simple way to determine if a
    > basic::string value is comprised only of numeric digits? I have an
    > application that parses a comma-delimited string, and I want to test if
    > specific values are strictly numeric. It was working until I got a
    > mixed alphanumeric value that started with a numeric digit (e.g.
    > "6btt123"), which caused the following code to fail:
    >
    > int ii = atoi(wStr.c_str());
    > if(ii) // numeric processing
    > {
    > // expecting purely numeric value in "ii"
    > [etc.]
    > }
    > else // alphanumeric processing
    > {
    > // process alphanumeric data
    > }
    > when it fell into the numeric processing branch.
    > I know that I could examine the contents of the "wStr" string
    > character-by-character to test if each character is a digit character,
    > but that seems slow and inefficient.


    Why do you think that iterating over the string and testing with
    isdigit() would be slower than using atoi()? After all atoi() would have
    to examine each character in the string as well, and would have to do
    some computation on top of that.
     
    Dombo, Feb 27, 2012
    #7
  8. Mike Copeland

    MikeWhy Guest

    Paul wrote:
    > On Feb 26, 10:22 pm, Ian Collins <> wrote:
    >> On 02/27/12 11:11 AM, Ian Collins wrote:
    >>
    >>
    >>
    >>> Never use atoi(), it has now way to indicate failure. Use strtol()
    >>> and check errno.

    >>
    >> Usual Monday morning keyboard issues: "no way to indicate failure.".
    >>
    >> --
    >> Ian Collins

    >
    > Whatabout isdigit?


    isdigit uses locale stuff, I think, and is not as trivial as you might like.
    (I might have that confused with atoi.)

    bool is_ascii_digit(char c)
    { return (c ^ 0x30) <= 9;
    }

    Xor flips the bits corresponding to 1's in the mask. ASCII digits are in the
    range 0x30 to 0x39. In other words, the high nybble has to contain 0x3.
    After xor'ing with 0x30 (or '0'), the high nybble can be zero only if the
    high nybble was 0x3. Any other value has a non-zero high nybble, and the <=
    test fails. The comparison also requires the low nybble is less than 0xa.
     
    MikeWhy, Feb 28, 2012
    #8
  9. Mike Copeland

    Paul Guest

    On Feb 28, 9:17 am, "MikeWhy" <> wrote:
    > Paul wrote:
    > > On Feb 26, 10:22 pm, Ian Collins <> wrote:
    > >> On 02/27/12 11:11 AM, Ian Collins wrote:

    >
    > >>> Never use atoi(), it has now way to indicate failure. Use strtol()
    > >>> and check errno.

    >
    > >> Usual Monday morning keyboard issues: "no way to indicate failure.".

    >
    > >> --
    > >> Ian Collins

    >
    > > Whatabout isdigit?

    >
    > isdigit uses locale stuff, I think, and is not as trivial as you might like.
    > (I might have that confused with atoi.)

    I think there are two versions of isdigit() one simple version is part
    of std string, the other is a template for use with locale. The locale
    version is very easy to use but it may be a little slower than the
    simpler version.
    >
    > bool is_ascii_digit(char c)
    > {    return (c ^ 0x30) <= 9;
    >
    > }
    >
    > Xor flips the bits corresponding to 1's in the mask. ASCII digits are in the
    > range 0x30 to 0x39. In other words, the high nybble has to contain 0x3.
    > After xor'ing with 0x30 (or '0'), the high nybble can be zero only if the
    > high nybble was 0x3. Any other value has a non-zero high nybble, and the <=
    > test fails. The comparison also requires the low nybble is less than 0xa.


    IIRC there is a more portable way to do this without using fixed hex
    values to mask so that it will work on any system, not just ASCII. I
    can't remember the exact algorithm right now though.
    The lib functions will probably be similar, and just as efficient.
     
    Paul, Feb 28, 2012
    #9
  10. Mike Copeland

    Marc Guest

    "MikeWhy" wrote:

    > bool is_ascii_digit(char c)
    > { return (c ^ 0x30) <= 9;
    > }
    >
    > Xor flips the bits corresponding to 1's in the mask. ASCII digits are in the
    > range 0x30 to 0x39. In other words, the high nybble has to contain 0x3.
    > After xor'ing with 0x30 (or '0'), the high nybble can be zero only if the
    > high nybble was 0x3. Any other value has a non-zero high nybble, and the <=
    > test fails. The comparison also requires the low nybble is less than 0xa.


    (unsigned)c-'0'<10 seems easier to remember...
     
    Marc, Feb 28, 2012
    #10
  11. Mike Copeland

    MikeWhy Guest

    "Marc" <> wrote in message
    news:jiira9$ceh$...
    > "MikeWhy" wrote:
    >
    >> bool is_ascii_digit(char c)
    >> { return (c ^ 0x30) <= 9;
    >> }
    >>
    >> Xor flips the bits corresponding to 1's in the mask. ASCII digits are in
    >> the
    >> range 0x30 to 0x39. In other words, the high nybble has to contain 0x3.
    >> After xor'ing with 0x30 (or '0'), the high nybble can be zero only if the
    >> high nybble was 0x3. Any other value has a non-zero high nybble, and the
    >> <=
    >> test fails. The comparison also requires the low nybble is less than 0xa.

    >
    > (unsigned)c-'0'<10 seems easier to remember...


    xor has a smaller carbon footprint. Subtraction has additional transistors
    in the borrow circuits, which consume power when flipping state. (Hell is
    exothermic, I believe, was the conclusion given in one such discussion.)
     
    MikeWhy, Feb 28, 2012
    #11
  12. Mike Copeland

    Quint Rankid Guest

    On Feb 26, 5:05 pm, (Mike Copeland) wrote:
    >    Is there a relatively easy and simple way to determine if a
    > basic::string value is comprised only of numeric digits?


    Maybe std::string::find_first_not_of.

    >    I know that I could examine the contents of the "wStr" string
    > character-by-character to test if each character is a digit character,
    > but that seems slow and inefficient.  Is there a better way to do such
    > processing?  Thoughts?  TIA


    I think you will have to examine each character. There may be ways to
    speed this up depending on how much knowledge you have about the
    data. IE, are there likely patterns that will occur with non-digits?
    Or are those cases what someone might informally describe as being
    random.


    Quint.
     
    Quint Rankid, Feb 28, 2012
    #12
    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. Replies:
    5
    Views:
    955
    X-Centric
    Jun 30, 2005
  2. darrel
    Replies:
    4
    Views:
    841
    darrel
    Jul 19, 2007
  3. jobs

    int to numeric numeric(18,2) ?

    jobs, Jul 21, 2007, in forum: ASP .Net
    Replies:
    2
    Views:
    991
    =?ISO-8859-1?Q?G=F6ran_Andersson?=
    Jul 22, 2007
  4. Rob Wahmann

    validate numeric range 6-10 digits

    Rob Wahmann, Feb 9, 2004, in forum: Javascript
    Replies:
    4
    Views:
    133
    Evertjan.
    Feb 9, 2004
  5. Cogito

    Testing for Numeric Data

    Cogito, Jul 8, 2004, in forum: Javascript
    Replies:
    5
    Views:
    121
Loading...

Share This Page