passing array to isdigit()

Discussion in 'C Programming' started by Carramba, Feb 9, 2005.

  1. Carramba

    Carramba Guest

    hi!

    I am trying to confirm if input is digit, so I thought it would by easy to
    do it with with isdigit() funktion,
    but how do I pass arrays to it if the imput is more then 1 sign?

    #include <stdio.h>
    #include <ctype.h>
    #include <stdlib.h>
    int main(){
    char a[3]; // enter 2 sign + \0

    scanf("%c", &a);
    if(isdigit(a[0]) && isdigit(a[1])) {printf("japp");
    }
    else{
    printf("nopp");
    }

    printf("\n\na[0]=>%d a[1]=>%d", a[0], a[1]);
    return 0;
    }



    getting output:
    12
    nopp

    2359144


    --
    Thanx in advance!

    ;-)

    ______________________________________
    I se the lightat the end, but every time I take a step it's get dim.
    Carramba, Feb 9, 2005
    #1
    1. Advertising

  2. Carramba

    Eric Sosman Guest

    Carramba wrote:
    > hi!
    >
    > I am trying to confirm if input is digit, so I thought it would by easy to
    > do it with with isdigit() funktion,
    > but how do I pass arrays to it if the imput is more then 1 sign?
    >
    > #include <stdio.h>
    > #include <ctype.h>
    > #include <stdlib.h>
    > int main(){
    > char a[3]; // enter 2 sign + \0
    >
    > scanf("%c", &a);


    Here's the problem: "%c" reads only one character, so
    only a[0] receives input. a[1] and a[2] remain unchanged,
    containing "random garbage" (which may or may not include
    the '\0' you mention). What you probably want is

    scanf("%2s", a);

    Note the change from "c" (read one character) to "s" (read
    a string), the inclusion of "2" to limit the string length
    to the amount the a[] array can hold, and the removal of
    the `&' operator.

    > if(isdigit(a[0]) && isdigit(a[1])) {printf("japp");


    Here's another problem, probably not involved in your
    trouble but a problem nonetheless. Write

    if (isdigit( (unsigned char)a[0] ) && ...

    to guard against character codes with negative values. All
    of the digits 0-9 have positive codes, but characters like
    'ß' and 'ø' may be negative on some machines. If the user
    enters such a character, you cannot safely use isdigit() on
    it until you convert it to a non-negative value.

    --
    Eric Sosman, Feb 9, 2005
    #2
    1. Advertising

  3. Carramba

    Michael Mair Guest

    Carramba wrote:
    > hi!
    >
    > I am trying to confirm if input is digit, so I thought it would by easy
    > to do it with with isdigit() funktion,
    > but how do I pass arrays to it if the imput is more then 1 sign?


    You mean: more than one character.
    There are several ways to go about this:
    1) You have a string and pass it to a function which runs through the
    whole string and checks every character (but not the string terminator)
    with isdigit(). If you encounter non-digit, you return false.
    2) You have an array of char and the number of potential digit
    characters. Do as above and pass array and length but instead of
    checking against the string terminator, run through all potential
    digits using the length you got passed.
    3) The strtol() function will convert a string into a long value.
    Its interface provides the means to check whether the last digit
    read was the last character before the string terminator.
    Leading white spaces might be discarded -- just look it up.
    4) Use sscanf() plus scanset restricted to the digits and get also
    the number of read characters. If it equals the string length,
    you know everything was a digit.

    >
    > #include <stdio.h>
    > #include <ctype.h>
    > #include <stdlib.h>
    > int main(){
    > char a[3]; // enter 2 sign + \0
    >
    > scanf("%c", &a);

    You mean
    int n, onlydigits;
    if( 1 != scanf("%2s%n", a, &n))
    {
    /* Deal with error */
    }
    if (strlen(a)!=n) { /* We read more characters than expected */ }

    > if(isdigit(a[0]) && isdigit(a[1]))


    onlydigits = 1;
    for (n=0; n<strlen(a); n++)
    if (!isdigit(a[n]))
    onlydigits = 0;
    if(onlydigits)

    > {printf("japp");
    > }
    > else{
    > printf("nopp");
    > }
    >
    > printf("\n\na[0]=>%d a[1]=>%d", a[0], a[1]);
    > return 0;
    > }
    >
    >
    >
    > getting output:
    > 12
    > nopp
    >
    > 2359144
    >
    >


    -Michael
    --
    E-Mail: Mine is a gmx dot de address.
    Michael Mair, Feb 9, 2005
    #3
  4. Carramba

    Luke Wu Guest

    Carramba wrote:
    > hi!
    >
    > I am trying to confirm if input is digit, so I thought it would by

    easy to
    > do it with with isdigit() funktion,
    >


    I think you are trying to get either a 1 digit number or a 2 digit
    number from the user (judging by your 3 element character array, where
    1 of the elements would be for null).

    >
    > but how do I pass arrays to it if the imput is more then 1 sign?
    >


    By sign I assume you mean digit. You can't pass arrays to isdigit().

    >
    >
    > #include <stdio.h>
    > #include <ctype.h>
    > #include <stdlib.h>
    >


    why did you add stdlib.h?

    >
    > int main(){
    > char a[3]; // enter 2 sign + \0
    >


    Assuming you meant 2 digits and null.

    >
    >
    > scanf("%c", &a);
    >


    You are sending scanf the address of the whole array, while it expects
    the address of a single character only. This invokes UB (type
    mismatch), but since the address of an array is equivalent(in value not
    type) to the address of the first element of the array, your program
    might just fill the first element of a (a[0]) with the charcter it gets
    from stdin. a[1] and a[2] will definitely be untouched (and since your
    array is automatic, most likely will contain garbage).

    >
    > if(isdigit(a[0]) && isdigit(a[1])) {printf("japp");
    >


    a[1] contains garbage, so dont' be suprised if the condition in the if
    clause evaluates to false.

    >
    > }
    > else{
    > printf("nopp");
    > }
    >
    > printf("\n\na[0]=>%d a[1]=>%d", a[0], a[1]);
    > return 0;
    > }
    >



    Hereis my version of a program that takes input and checks if the user
    entered a 1 or 2 digit number (don't trust scanf or gets):



    #include <stdio.h> /* for getchar(), printf() & puts() */
    #include <string.h> /* for strchr() */
    #include <stdlib.h> /* for abs(), strtol(), and exit() */

    int main()
    {
    char c; /* for stdin consuming while loop */
    char input[10]; /* holds user character input */
    char *chptr; /* for error checks in fgets() & strtol() */
    long number; /* number after conversion by strotol */

    printf("Input a 1 or 2 digit number and hit enter: ");
    fflush(stdout);

    chptr = fgets(input, sizeof input, stdin); /* user input into
    buffer */
    if(chptr == NULL)
    {
    puts("ERROR: fgets failed, press Enter to exit");
    getchar();
    exit(EXIT_FAILURE);
    }

    /* following if-while eats all the leftover characters in stdin
    upto and including the newline (which must be still in stdin
    if it isn't inside our input buffer */
    if(!strchr(input, '\n'))
    while((c = getchar()) != '\n');


    number = strtol(input, &chptr, 0); /* convert to long interger */


    /* if absolute value of number is between 0 and 99, then the user
    must have entered a 1 or 2 digit number; if the user entered
    something weird, strtol can still return '0' but endptr will
    point to first element of buffer if that is so; so we must
    make sure that chptr != &input[0] or chptr != input in our if */

    if( abs(number) >= 0 && abs(number) <= 99 && chptr != input)
    {
    /* user entered a 1 or 2 digit number */
    printf("yapp, %ld is good input\n\n", number);
    }
    else if( chptr == input)
    {
    /* user entered weird input (not number) */
    printf("nopp, that wasn't even a number!!\n\n");
    }
    else
    {
    /* user entered > 2 digit number */
    printf("nopp, wasn't a 1 or 2 digit number\n\n");
    }

    puts("Program Finished: Press enter to exit");
    getchar();
    return EXIT_SUCCESS;
    }


    If the program above confuses you, good, because confusion is what
    forces us to
    investigate, and investigation brings enlightenment (last year I had no
    clue why most experts used fgets, now I use it all the time).

    Good luck.
    Luke Wu, Feb 9, 2005
    #4
  5. Carramba

    Flash Gordon Guest

    Carramba wrote:
    > hi!
    >
    > I am trying to confirm if input is digit, so I thought it would by easy
    > to do it with with isdigit() funktion,
    > but how do I pass arrays to it if the imput is more then 1 sign?


    With isdigit you have to check characters 1 at a time.

    > #include <stdio.h>
    > #include <ctype.h>
    > #include <stdlib.h>
    > int main(){
    > char a[3]; // enter 2 sign + \0
    >
    > scanf("%c", &a);


    You are only reading 1 character here, however many the user enters. So
    a[1] is still uninitialised in the line below.

    > if(isdigit(a[0]) && isdigit(a[1])) {printf("japp");
    > }
    > else{
    > printf("nopp");
    > }
    >
    > printf("\n\na[0]=>%d a[1]=>%d", a[0], a[1]);


    You need to terminate the last line with a line feed or it might not be
    displayed.

    > return 0;
    > }
    >
    >
    >
    > getting output:
    > 12
    > nopp
    >
    > 2359144

    --
    Flash Gordon
    Living in interesting times.
    Although my email address says spam, it is real and I read it.
    Flash Gordon, Feb 9, 2005
    #5
  6. Carramba

    CBFalconer Guest

    Luke Wu wrote:
    >

    .... snip ...
    >
    > If the program above confuses you, good, because confusion is what
    > forces us to investigate, and investigation brings enlightenment
    > (last year I had no clue why most experts used fgets, now I use it
    > all the time).


    Now try out ggets (and fggets) which you can get at:

    <http://cbfalconer.home.att.net/download/>

    and maybe you won't want to bother with all those tests on the
    results from fgets.

    --
    "If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers." - Keith Thompson
    CBFalconer, Feb 9, 2005
    #6
  7. Carramba

    Michael Mair Guest

    Eric Sosman wrote:
    >
    > Carramba wrote:
    >
    >> if(isdigit(a[0]) && isdigit(a[1])) {printf("japp");

    >
    >
    > Here's another problem, probably not involved in your
    > trouble but a problem nonetheless. Write
    >
    > if (isdigit( (unsigned char)a[0] ) && ...
    >
    > to guard against character codes with negative values. All
    > of the digits 0-9 have positive codes, but characters like
    > 'ß' and 'ø' may be negative on some machines. If the user
    > enters such a character, you cannot safely use isdigit() on
    > it until you convert it to a non-negative value.


    I have a question on this one: Does this follow from
    C99, 7.4 Character handling
    #1:
    "The header <ctype.h> declares several functions useful for classifying
    and mapping characters. In all cases the argument is an int, the value
    of which shall be representable as an unsigned char or shall equal the
    value of the macro EOF. If the argument has any other value, the
    behavior is undefined."
    or is there another source as well?
    Accidentally, I just have got a request for a "ANSI C" program where
    I have to use isalpha() extensively. Depending on the locale, the
    above might be an issue, so I want to get that right and know why.
    Essentially, I also would have to assert(UCHAR_MAX<=INT_MAX),
    wouldn't I?

    Cheers
    Michael
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.
    Michael Mair, Feb 9, 2005
    #7
  8. > Eric Sosman wrote:
    > > Carramba wrote:
    > >
    > > > if(isdigit(a[0]) && isdigit(a[1])) {printf("japp");

    > >
    > > Here's another problem, probably not involved in your
    > > trouble but a problem nonetheless. Write
    > >
    > > if (isdigit( (unsigned char)a[0] ) && ...
    > >
    > > to guard against character codes with negative values. All
    > > of the digits 0-9 have positive codes, but characters like
    > > 'ß' and 'ø' may be negative on some machines. If the user
    > > enters such a character, you cannot safely use isdigit() on
    > > it until you convert it to a non-negative value.


    As I argued in a previous thread, it's more robust to use
    aliasing, than conversion...

    unsigned char *p = &a[0];

    if (isdigit(p[0]) && ...

    Michael Mair wrote:
    >
    > I have a question on this one: Does this follow from
    > C99, 7.4 Character handling
    > #1:
    > "The header <ctype.h> declares several functions useful for
    > classifying and mapping characters. In all cases the argument
    > is an int, the value of which shall be representable as an
    > unsigned char or shall equal the value of the macro EOF.
    > If the argument has any other value, the behavior is undefined."


    Yes.

    > or is there another source as well?
    > Accidentally, I just have got a request for a "ANSI C" program
    > where I have to use isalpha() extensively. Depending on the
    > locale, the above might be an issue, so I want to get that right
    > and know why. Essentially, I also would have to assert
    > (UCHAR_MAX<=INT_MAX), wouldn't I?


    Depends how paranoid you are. It's arguable whether a hosted
    implementation where UCHAR_MAX > INT_MAX can ever be conforming.

    [For instance, (fputc)() would no longer guarantee that a rereading
    a written byte would reproduce the original. But some argue
    this is a QoI issue.]

    --
    Peter
    Peter Nilsson, Feb 10, 2005
    #8
  9. Carramba

    Eric Sosman Guest

    Michael Mair wrote:
    > Eric Sosman wrote:
    >
    >>
    >> Carramba wrote:
    >>
    >>> if(isdigit(a[0]) && isdigit(a[1])) {printf("japp");

    >>
    >> Here's another problem, probably not involved in your
    >> trouble but a problem nonetheless. Write
    >>
    >> if (isdigit( (unsigned char)a[0] ) && ...
    >>
    >> to guard against character codes with negative values. All
    >> of the digits 0-9 have positive codes, but characters like
    >> 'ß' and 'ø' may be negative on some machines. If the user
    >> enters such a character, you cannot safely use isdigit() on
    >> it until you convert it to a non-negative value.

    >
    > I have a question on this one: Does this follow from
    > C99, 7.4 Character handling
    > #1:
    > "The header <ctype.h> declares several functions useful for classifying
    > and mapping characters. In all cases the argument is an int, the value
    > of which shall be representable as an unsigned char or shall equal the
    > value of the macro EOF. If the argument has any other value, the
    > behavior is undefined."
    > or is there another source as well?


    Yes, that's the crucial paragraph. You must guarantee
    that the argument to isxxx() is either EOF or a non-negative
    value, specifically, a non-negative value corresponding to
    a character code represented as an unsigned char. Informally,
    the isxxx() argument must be in { EOF, 0..UCHAR_MAX }.

    For values returned by getc() and friends no special
    precautions need be taken: the returned value is exactly what
    isxxx() expects, and you can pass it directly without fuss.
    The surprises occur when you store a character code in a `char',
    because `char' is a signed type on some implementations. If a
    particular `char' has a negative value, it will (usually) become
    a negative-valued `int' upon promotion, and if so will not be
    in the range { 0..UCHAR_MAX }. If you're lucky(?) the negative
    `char' will just happen to have the same value as EOF and you'll
    avoid undefined behavior -- but at the cost of massive confusion.

    Peter Nilsson suggests processing a string by converting its
    `char*' pointer to `unsigned char*':

    char *string = ...;
    unsigned char *safe = (unsigned char*)string;
    if (isxxx(*safe)) ...

    While this will work on Every Single C Implementation I Have
    Ever Encountered, it is in fact "lying to the compiler," and
    thus braving the compiler's revenge. The thing that `string'
    points to is a plain `char', not an `unsigned char', and it is
    (very mildly) risky to pretend that the one is the other. I am
    too full of post-prandial Cognac at the moment to work out the
    details, but I rather suspect that a system with signed `char'
    and ones' complement representation for negatives might get into
    some trouble with such a lie. Since the incorruptibly honest
    convert-at-point-of-call idiom cannot fail while the pointer-
    twiddling approach carries with it a faint whiff of impropriety,
    I see no reason to use the latter.

    > Accidentally, I just have got a request for a "ANSI C" program where
    > I have to use isalpha() extensively. Depending on the locale, the
    > above might be an issue, so I want to get that right and know why.
    > Essentially, I also would have to assert(UCHAR_MAX<=INT_MAX),
    > wouldn't I?


    The characteristics of getc() and isxxx() seem to rule out
    some "exotic" architectures, or at least to constrain them. If
    If UCHAR_MAX <= INT_MAX all's well, but if UCHAR_MAX > INT_MAX
    there are some `unsigned char' values that cannot be returned from
    getc() or passed to isxxx(). The only way out of this predicament,
    I think, is to say that such values do not correspond to legitimate
    character codes for the implementation at hand. You might have
    INT_MAX == 32767 and UCHAR_MAX == 65535, but if getc() can only
    return values in the set { EOF, 0..511 }, say, all will still be
    well.

    Incidentally, note that a system with signed `char' must
    either limit itself to non-negative codes for actual characters
    or must provide a useful definition for the conversion of out-
    of-range `unsigned char' values to plain signed `char'. It
    would be unconscionable if

    int ch;
    char c;
    if ((ch = getchar()) != EOF)
    c = ch;

    .... were to raise a signal or do "something weird" if `ch'
    happened to exceed CHAR_MAX. The library was born as the servant
    of the language, but now and then becomes its master.

    With 20-20 hindsight one can opine that the original decision
    to leave the signedness of `char' unspecified was unfortunate.
    However, one can't lay the blame on Ritchie; he observed that
    different machines took different positions on the matter and
    decided not to make implementing his new language difficult for
    half of them. So many of his other decisions turned out well that
    it's hard to chastise him -- indeed, it's hard to do other than
    admire him. "Too bad," nonetheless.

    --
    Eric Sosman
    lid
    Eric Sosman, Feb 10, 2005
    #9
  10. Eric Sosman wrote:
    >
    > Peter Nilsson suggests processing a string by converting its
    > `char*' pointer to `unsigned char*':
    >
    > char *string = ...;
    > unsigned char *safe = (unsigned char*)string;
    > if (isxxx(*safe)) ...
    >
    > While this will work on Every Single C Implementation I Have
    > Ever Encountered, it is in fact "lying to the compiler," and
    > thus braving the compiler's revenge.


    No. The way I see it, it's countering a lie from the implementation.

    Ordinary character strings should really be stored as unsigned char,
    non-negative codings. This is how they're written and read by
    implementations.

    Suppose I have an input sequence along the lines of...

    char blah[42];
    fgets(blah, sizeof blah, stdin);

    Suppose the user enters "Café", and suppose we have an 8-bit
    implementation where é's character code is 233. How is this stored
    in blah?

    The standard requires that 233 is stored as a 'byte', as in...

    * (unsigned char *) &blah[3] = 233;

    Subsequent examination of blah[3] via a char lvalue will _not_
    yield the original character coding. Converting the plain char
    value to unsigned char, may also fail to yield the original
    character coding. Since isxxxx operates on the original character
    coding, then it seems obvious sense to use an unsigned char
    lvalue, rather than conversion of a plain char to unsigned char.

    > The thing that `string' points to is a plain `char', not an
    > `unsigned char', and it is (very mildly) risky to pretend that
    > the one is the other.


    Unfortunately, that is what the standard tells implementations
    to do!

    > I am too full of post-prandial Cognac at the moment to work
    > out the details, but I rather suspect that a system with
    > signed `char' and ones' complement representation for negatives
    > might get into some trouble with such a lie.


    I agree. And I think the standard should explicitly require
    plain char to be unsigned on 1c or sm machines, or 2c C99
    implementations where CHAR_MIN might be a 'non-value'.

    > Since the incorruptibly honest convert-at-point-of-call idiom
    > cannot fail


    I've demonstrated above that it can.

    > while the pointer-twiddling approach carries with it a faint
    > whiff of impropriety, I see no reason to use the latter.


    I've demonstrated that consistent use of unsigned char lvalues
    _can't_ fail!

    > ...
    > Incidentally, note that a system with signed `char' must
    > either limit itself to non-negative codes for actual characters
    > or must provide a useful definition for the conversion of out-
    > of-range `unsigned char' values to plain signed `char'. It
    > would be unconscionable if
    >
    > int ch;
    > char c;
    > if ((ch = getchar()) != EOF)
    > c = ch;
    >
    > ... were to raise a signal or do "something weird" if `ch'
    > happened to exceed CHAR_MAX. The library was born as the servant
    > of the language, but now and then becomes its master.


    For consistency with other aspects of implementation requirements,
    this should really be written as...

    int ch;
    unsigned char c;
    if ((ch = getchar()) != EOF)
    c = ch;

    > With 20-20 hindsight


    It's wonderful, isn't it! :)

    > one can opine that the original decision to leave the
    > signedness of `char' unspecified was unfortunate.


    That character types have duplicate roles of byte and
    character stores was also unfortunate.

    --
    Peter
    Peter Nilsson, Feb 10, 2005
    #10
  11. Carramba

    Eric Sosman Guest

    Peter Nilsson wrote:
    > Eric Sosman wrote:
    >
    >> Peter Nilsson suggests processing a string by converting its
    >>`char*' pointer to `unsigned char*':
    >>
    >> char *string = ...;
    >> unsigned char *safe = (unsigned char*)string;
    >> if (isxxx(*safe)) ...
    >>
    >>While this will work on Every Single C Implementation I Have
    >>Ever Encountered, it is in fact "lying to the compiler," and
    >>thus braving the compiler's revenge.

    >
    >
    > No. [...]


    (Shrug.) Have it your way, then.

    --
    Eric Sosman
    lid
    Eric Sosman, Feb 10, 2005
    #11
  12. On Wed, 09 Feb 2005 17:29:00 +0100, Michael Mair
    <> wrote:

    >
    >
    > Carramba wrote:
    > > hi!
    > >
    > > I am trying to confirm if input is digit, so I thought it would by easy
    > > to do it with with isdigit() funktion,
    > > but how do I pass arrays to it if the imput is more then 1 sign?


    BTW in English we say character, or in general use mark or symbol but
    in computer programming symbol has a different meaning; or very
    formally glyph. 'Sign' means specifically plus + or minus/hyphen -.

    >
    > You mean: more than one character.
    > There are several ways to go about this:
    > 1) You have a string and pass it to a function which runs through the
    > whole string and checks every character (but not the string terminator)
    > with isdigit(). If you encounter non-digit, you return false.
    > 2) You have an array of char and the number of potential digit
    > characters. Do as above and pass array and length but instead of
    > checking against the string terminator, run through all potential
    > digits using the length you got passed.


    Agree.

    > 3) The strtol() function will convert a string into a long value.
    > Its interface provides the means to check whether the last digit
    > read was the last character before the string terminator.
    > Leading white spaces might be discarded -- just look it up.


    Optional leading whitespace and optional sign (in the sense above).
    Even the unsigned versions strtoul and strtoull accept a sign, even a
    minus/negative sign! And it fails to accept a string that is digits
    but whose numeric value overflows the return type.

    > 4) Use sscanf() plus scanset restricted to the digits and get also
    > the number of read characters. If it equals the string length,
    > you know everything was a digit.
    >

    Equals the length or (equivalently) identifies the end (terminator).

    5) Use strspn() and check if return equals length or identifies end.


    - David.Thompson1 at worldnet.att.net
    Dave Thompson, Feb 14, 2005
    #12
  13. Carramba

    Michael Mair Guest

    Dave Thompson wrote:
    > On Wed, 09 Feb 2005 17:29:00 +0100, Michael Mair
    > <> wrote:
    >
    >
    >>
    >>Carramba wrote:
    >>
    >>>hi!
    >>>
    >>>I am trying to confirm if input is digit, so I thought it would by easy
    >>>to do it with with isdigit() funktion,
    >>>but how do I pass arrays to it if the imput is more then 1 sign?

    >
    >
    > BTW in English we say character, or in general use mark or symbol but
    > in computer programming symbol has a different meaning; or very
    > formally glyph. 'Sign' means specifically plus + or minus/hyphen -.
    >
    >
    >>You mean: more than one character.
    >>There are several ways to go about this:
    >>1) You have a string and pass it to a function which runs through the
    >>whole string and checks every character (but not the string terminator)
    >>with isdigit(). If you encounter non-digit, you return false.
    >>2) You have an array of char and the number of potential digit
    >>characters. Do as above and pass array and length but instead of
    >>checking against the string terminator, run through all potential
    >>digits using the length you got passed.

    >
    >
    > Agree.
    >
    >
    >>3) The strtol() function will convert a string into a long value.
    >>Its interface provides the means to check whether the last digit
    >>read was the last character before the string terminator.
    >>Leading white spaces might be discarded -- just look it up.

    >
    > Optional leading whitespace and optional sign (in the sense above).
    > Even the unsigned versions strtoul and strtoull accept a sign, even a
    > minus/negative sign! And it fails to accept a string that is digits
    > but whose numeric value overflows the return type.


    Ack. You are right, of course.

    >>4) Use sscanf() plus scanset restricted to the digits and get also
    >>the number of read characters. If it equals the string length,
    >>you know everything was a digit.

    >
    > Equals the length or (equivalently) identifies the end (terminator).


    I am not sure what you want to say here -- do you agree with me
    and just expand what I said?


    > 5) Use strspn() and check if return equals length or identifies end.


    I always forget strspn()/strcspn()... Thanks for the reminder :)


    Cheers
    Michael
    --
    E-Mail: Mine is a gmx dot de address.
    Michael Mair, Feb 14, 2005
    #13
  14. Carramba

    CBFalconer Guest

    Michael Mair wrote:
    > Dave Thompson wrote:
    >> lid> wrote:
    >>

    .... snip ...
    >>
    >>> 3) The strtol() function will convert a string into a long value.
    >>> Its interface provides the means to check whether the last digit
    >>> read was the last character before the string terminator.
    >>> Leading white spaces might be discarded -- just look it up.

    >>
    >> Optional leading whitespace and optional sign (in the sense
    >> above). Even the unsigned versions strtoul and strtoull accept
    >> a sign, even a minus/negative sign! And it fails to accept a
    >> string that is digits but whose numeric value overflows the
    >> return type.

    >
    > Ack. You are right, of course.


    Except that you can use the endptr parameter and ignore the
    overflow. If (endptr != s) after the call, some sequence was
    found, and *endptr is the non-digit that ended it. This will
    absorb leading blanks and sign. So for all digits:

    strtol(s, &endptr, 10);
    alldigits = isdigit((unsigned char)*s) && (!*endptr);

    --
    "If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers." - Keith Thompson
    CBFalconer, Feb 14, 2005
    #14
  15. On Mon, 14 Feb 2005 11:26:31 +0100, Michael Mair
    <> wrote:

    >
    >
    > Dave Thompson wrote:
    > > On Wed, 09 Feb 2005 17:29:00 +0100, Michael Mair
    > > <> wrote:

    <snip: strto* overflow: CBFalconer already corrected>
    <snip>
    > >>4) Use sscanf() plus scanset restricted to the digits and get also
    > >>the number of read characters. If it equals the string length,
    > >>you know everything was a digit.

    > >
    > > Equals the length or (equivalently) identifies the end (terminator).

    >
    > I am not sure what you want to say here -- do you agree with me
    > and just expand what I said?
    >

    Agree and expand.
    int n = 0, ret = sscanf (buf, "%*[0-9]%n", &n);
    /* range notation not standard do the obvious */

    if( ret>=0 && n == strlen(buf) ) /* all scanned OK */
    /* or */
    if( ret>=0 && buf[n] == 0 ) /* or !buf[n] */ /* all scanned OK */
    The second way is debatably more idiomatic and often a little faster.

    - David.Thompson1 at worldnet.att.net
    Dave Thompson, Feb 21, 2005
    #15
  16. Carramba

    Michael Mair Guest

    Dave Thompson wrote:
    > On Mon, 14 Feb 2005 11:26:31 +0100, Michael Mair
    > <> wrote:
    >
    >
    >>
    >>Dave Thompson wrote:
    >>
    >>>On Wed, 09 Feb 2005 17:29:00 +0100, Michael Mair
    >>><> wrote:

    >
    > <snip: strto* overflow: CBFalconer already corrected>
    > <snip>
    >
    >>>>4) Use sscanf() plus scanset restricted to the digits and get also
    >>>>the number of read characters. If it equals the string length,
    >>>>you know everything was a digit.
    >>>
    >>>Equals the length or (equivalently) identifies the end (terminator).

    >>
    >>I am not sure what you want to say here -- do you agree with me
    >>and just expand what I said?
    >>

    >
    > Agree and expand.
    > int n = 0, ret = sscanf (buf, "%*[0-9]%n", &n);
    > /* range notation not standard do the obvious */
    >
    > if( ret>=0 && n == strlen(buf) ) /* all scanned OK */
    > /* or */
    > if( ret>=0 && buf[n] == 0 ) /* or !buf[n] */ /* all scanned OK */
    > The second way is debatably more idiomatic and often a little faster.


    Thank you for clarifying :)
    --
    E-Mail: Mine is a gmx dot de address.
    Michael Mair, Feb 21, 2005
    #16
    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. Alf P. Steinbach

    isdigit() for characters greater than 127

    Alf P. Steinbach, Oct 9, 2004, in forum: C++
    Replies:
    4
    Views:
    3,221
    James Gregory
    Oct 9, 2004
  2. Replies:
    9
    Views:
    556
    Andreas Leitgeb
    Feb 9, 2007
  3. mdh

    isdigit

    mdh, Oct 6, 2006, in forum: C Programming
    Replies:
    10
    Views:
    811
  4. MooMaster
    Replies:
    2
    Views:
    390
    Dan Bishop
    May 1, 2008
  5. Donkey Hottie

    Re: print problem using isDigit

    Donkey Hottie, Sep 29, 2008, in forum: Java
    Replies:
    4
    Views:
    365
    RedGrittyBrick
    Sep 29, 2008
Loading...

Share This Page