c400-l-bounces@xxxxxxxxxxxx wrote on 10/07/2004 04:36:36 PM:
>
> C is not my 'native' language, so I'm asking what the most efficient way
> to validate a string as containing a numeric value is.  The ato?() and
> sscanf() functions just stop when they encounter a non-numeric, but do
> not tell you that they did.
>
> I need to verify that a string contains a valid numeric value.  (I.E. "
> +100" not "1 + 00" nor even "1+00  ", let alone "BOB   ")  (ato?() &
> sscanf() would return NULL or 1 in each case.)

Somebody else already pointed you in the right direction, I think --
to strtol -- and the validation step is straightforward.  Now, I'm not
sure it's the most efficient, but I'll bet a dollar to a donut that
strtol is pretty doggoned tight.

NOTE: strtol disregards leading whitespace, so ' 1' is as good as '1' --
not sure how that might fit with your requirements.

The signature for strtol is:

long strtol (const char* String, char **EndPointer, int Base)

It's the EndPointer parameter that is the key to validation.
If the conversion is flawless, then the EndPointer you pass
will point to the null character '\0' at the end of the string.
Otherwise, it will point to the first character not consistent
with the 'Base' parameter.

Here's a little program you can play with that will exhibit this
behavior.  Basically, a validation just must ensure that endPtr
is pointing to a null character (presuming you don't want to
allow any trailing gorp.)

What it does is take each parm from the command line and try
to use strtol on it.  Note that to pass strings with embedded
blanks you need to quote the strings, i.e.

     on AIX:   ./a.out "123" " 123" "  +123" "1+00"
     QCMD:     CALL TRYSTRTOL PARM(' 1+00' '1+00' '100')

Have fun!

------------ 8< ----- cut here ----- 8< --------------
#include <stdio.h>
int main (int argc, char *argv[])
{
    int i;
    char *endPtr;
    for (i=0; i<argc; ++i) {
        long res = strtol(argv[i], &endPtr, 10);
        printf("Called strtol on '%s' [%p]\n", argv[i], argv[i]);
        printf("  return :  %10d\n", res);
        printf("  endPtr :  %10p\n", endPtr);
        printf("  *endPtr:  '%c'\n", (endPtr)? *endPtr : '-');
    }
    return 0;
}
--------- 8< ------- cut here ----- 8< --------------

--- sample invocation (i5/OS) ------------------------------
   Called strtol on 'QGPL/TRYSTRTOL' [SPP:0000 :1aefQPADEV0001BLAIR
090668 :
   170:0:1230]
     return :           0
     endPtr :  SPP:0000 :1aefQPADEV0001BLAIR     090668 :170:0:1230
     *endPtr:  'Q'
   Called strtol on ' 1+00' [SPP:0000 :19efQCAWAREA :646:1:1230]
     return :           1
     endPtr :  SPP:0000 :19efQCAWAREA :648:2:1230
     *endPtr:  '+'
   Called strtol on '1+00' [SPP:0000 :19efQCAWAREA :667:3:1230]
     return :           1
     endPtr :  SPP:0000 :19efQCAWAREA :668:4:1230
     *endPtr:  '+'
   Called strtol on '100' [SPP:0000 :19efQCAWAREA :688:5:1230]
     return :         100
     endPtr :  SPP:0000 :19efQCAWAREA :68b:6:1230
     *endPtr:  ' '
   Press ENTER to end terminal session.



--- sample invocation (AIX) --------------------------------
.../usr1/blair/src % ./a.out "1+00" " 1+00" "1 + 0" "1"
Called strtol on './a.out' [2ff21d10]
  return :           0
  endPtr :    2ff21d10
  *endPtr:  '.'
Called strtol on '1+00' [2ff21d18]
  return :           1
  endPtr :    2ff21d19
  *endPtr:  '+'
Called strtol on ' 1+00' [2ff21d1d]
  return :           1
  endPtr :    2ff21d1f
  *endPtr:  '+'
Called strtol on '1 + 0' [2ff21d23]
  return :           1
  endPtr :    2ff21d24
  *endPtr:  ' '
Called strtol on '1' [2ff21d29]
  return :           1
  endPtr :    2ff21d2a
  *endPtr:  '\000'


HTH.


-blair



This thread ...

Replies:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2019 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].