Converting large strings to numbers

R

rouble

Without using errno, is there a portable way to detect if a string
number is not within the range 0 to 4294967295.

Currently I am using strtoul. I can check the string for "-" as the
first character before calling strtoul, so I can figure out if the
value is less than 0.

My issue arises when the number is greater than 4294967295 on platforms
where ULONG_MAX is 4294967295; in this case strtoul will return
ULONG_MAX and set errno to ERANGE. However, some platforms I work on do
not support errno. So there is no way for me to know that the value was
greater than 4294967295.

Is there another way to do this ?

TIA,
rouble
 
W

Walter Roberson

Without using errno, is there a portable way to detect if a string
number is not within the range 0 to 4294967295.
Currently I am using strtoul. I can check the string for "-" as the
first character before calling strtoul, so I can figure out if the
value is less than 0.
My issue arises when the number is greater than 4294967295 on platforms
where ULONG_MAX is 4294967295; in this case strtoul will return
ULONG_MAX and set errno to ERANGE. However, some platforms I work on do
not support errno. So there is no way for me to know that the value was
greater than 4294967295.

Stringify ULONG_MAX and do a strcmp() of the source number against
that value. If the source number is all digits then strcmp() of the
decimal representations is equivilent to a numeric comparison.
Even in odd character sets, because of the C standard's specifi
rules about the representation of the digits.
 
D

David Resnick

Without using errno, is there a portable way to detect if a string
number is not within the range 0 to 4294967295.

Currently I am using strtoul. I can check the string for "-" as the
first character before calling strtoul, so I can figure out if the
value is less than 0.

My issue arises when the number is greater than 4294967295 on platforms
where ULONG_MAX is 4294967295; in this case strtoul will return
ULONG_MAX and set errno to ERANGE. However, some platforms I work on do
not support errno. So there is no way for me to know that the value was
greater than 4294967295.

Is there another way to do this ?

TIA,
rouble

Well, if strtoul returns ULONG_MAX, you could compare the string being
converted to "4294967295". If it is NOT the same, you have overflowed.

-David
 
E

Eric Sosman

Without using errno, is there a portable way to detect if a string
number is not within the range 0 to 4294967295.

Currently I am using strtoul. I can check the string for "-" as the
first character before calling strtoul, so I can figure out if the
value is less than 0.

My issue arises when the number is greater than 4294967295 on platforms
where ULONG_MAX is 4294967295; in this case strtoul will return
ULONG_MAX and set errno to ERANGE. However, some platforms I work on do
not support errno. So there is no way for me to know that the value was
greater than 4294967295.

Is there another way to do this ?

A platform that doesn't "support errno" is a non-conforming
implementation of C, so you're in uncertain territory at best.
One possibility, of course, is to write your own replacement; if
the implementation is already known to be non-conforming and
hence suspect, this may be the safest course.

If you can at least trust strtoul() to return ULONG_MAX for
an out-of-range number, you could conclude that any other value
is legitimate. When ULONG_MAX shows up, you could inspect the
string itself to see whether it was in fact "4294967295" (or
"037777777777" or "0xFFFFFFFF" or ... it'll be a little more
trouble than a mere strcmp(), and the tests will depend on the
value of strtoul()'s third argument). Or (if circumstances
permit) you could just treat ULONG_MAX as an error, sacrificing
the possibility of actually handling that single large number.
 
C

CBFalconer

Without using errno, is there a portable way to detect if a string
number is not within the range 0 to 4294967295.

Currently I am using strtoul. I can check the string for "-" as the
first character before calling strtoul, so I can figure out if the
value is less than 0.

My issue arises when the number is greater than 4294967295 on
platforms where ULONG_MAX is 4294967295; in this case strtoul will
return ULONG_MAX and set errno to ERANGE. However, some platforms I
work on do not support errno. So there is no way for me to know that
the value was greater than 4294967295.

Is there another way to do this ?

You obviously have a non-conformant implementation. However, you
can do the fundamental conversions yourself. For input from a
stream see txtio.zip, and if you need string input make the
appropriate changes yourself. See:

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

pete

Without using errno, is there a portable way to detect if a string
number is not within the range 0 to 4294967295.

Currently I am using strtoul. I can check the string for "-" as the
first character before calling strtoul, so I can figure out if the
value is less than 0.

My issue arises when the number
is greater than 4294967295 on platforms
where ULONG_MAX is 4294967295; in this case strtoul will return
ULONG_MAX and set errno to ERANGE.
However, some platforms I work on do
not support errno.
So there is no way for me to know that the value was
greater than 4294967295.

Is there another way to do this ?

Use strcmp instead of strtoul.

/* BEGIN new.c */

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

#define str(s) # s
#define xstr(s) str(s)

#define RANGE_1 "4294967295"

int all_digits(char *s);

int main(void)
{
char *range = RANGE_1;

/* char *range = xstr(ULONG_MAX); */
/* char *range = RANGE_1 */

char *strings[] = {
"0","","-1","4294967296","4294967296000",
"4294967294","4294967295", NULL
};
char **s = strings;

printf("\nRange is %s.\n\n", range);
while (*s != NULL) {
if (**s != '\0' && all_digits(*s)
&& 0 >= strcmp(*s, range)) {
printf("%s is in range.\n", *s);
} else {
printf("%s is out of range.\n", *s);
}
++s;
}
return 0;
}

int all_digits(char *s)
{
while(isdigit(*s)) {
++s;
}
return *s == '\0';
}

/* END new.c */
 
L

Lawrence Kirby

Stringify ULONG_MAX

Ok as long as you mean convert the value to a string with, say, sprintf()
and not by preprocessor tricks on the ULONG_MAX macro itself.
and do a strcmp() of the source number against
that value. If the source number is all digits then strcmp() of the
decimal representations is equivilent to a numeric comparison.

Unless there are leading zeros.
Even in
odd character sets, because of the C standard's specifi rules about the
representation of the digits.

It would still work even if the digits weren't contiguous in the character
set.

Lawrence
 
K

Keith Thompson

David Resnick said:
Well, if strtoul returns ULONG_MAX, you could compare the string being
converted to "4294967295". If it is NOT the same, you have overflowed.

Unless the string is "+4294967295", or "04294967295", or
"+0004294967295". That's if you use a "base" argument of 10; if you
set "base" to 0, a leading '0' implies octal, and you also have to
worry about "037777777777", "00037777777777", "0xffffffff",
"0X000FfFfFfFf", and so forth.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top