By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,405 Members | 1,365 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,405 IT Pros & Developers. It's quick & easy.

Re: Promoting unsigned long int to long int

P: n/a
pereges <Br*****@gmail.comwrites:
[...]
#define ulong unsigned long int
#define uchar unsigned char
[...]

These types already have perfectly good names already. Why give them
new ones?

If you must rename them for some reason, use typedefs, not macros.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 30 '08
Share this Question
Share on Google+
105 Replies


P: n/a
On Jul 1, 9:52 pm, Keith Thompson <ks...@mib.orgwrote:
>
What range checks are you referring to?

Get the types right first, then worry about range checking.
I mean checking if the value of a variable is within some permissible
range eg. an int should always be between INT_MIN and INT_MAX range
Jul 1 '08 #51

P: n/a
pereges <Br*****@gmail.comwrites:
On Jul 1, 9:52 pm, Keith Thompson <ks...@mib.orgwrote:
What range checks are you referring to?

Get the types right first, then worry about range checking.

I mean checking if the value of a variable is within some permissible
range eg. an int should always be between INT_MIN and INT_MAX range
An int *is* always between INT_MIN and INT_MAX, inclusive. Assuming
no trap representations or padding bits, it's simply impossible for an
int object to have a value outside that range. If you try to check it
yourself:
if (i < INT_MIN || i INTMAX) ...
the compiler is likely to optimize away the test.

If you're asking about validating input, that's a different matter.

If you have the input in a string, you can use one of the strto*()
functions to convert it to a numeric value. Unlike the *scanf()
functions, the strto*() functions have well-defined behavior on
overflow. See the documentation for details, and feel free to ask
more specific questions if you're still having problems.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jul 1 '08 #52

P: n/a
On Tue, 1 Jul 2008 04:27:44 -0700 (PDT), pereges <Br*****@gmail.com>
wrote:
>On Jul 1, 4:20 pm, "Joachim Schmitz" <nospam.j...@schmitz-digital.de>
wrote:
>No! To print the address of a use %p
But why is this caste needed when you are already using %lu ? Often

%lu tells printf to expect a long unsigned valie and read it off the stack
(or whatever the parameter passing method of you implementation might be), a
is a size_t which may or may not be the same size, but printf doesn't know,
so it grabs an unsigned long and possible touches something that isn't
allowew or supposed to touch.
when I want to use chars as ints, I don't use any caste. I simply do :
char a;
scanf("%d", &a);
And it works.

%d expects an int, so the scanf reads an int and places it in a char, loos
of precision and sign may occur.

I'm sorry I mean while scanning a not printing it :

size_t a;
scanf("%lu", &a);

Is this operation correct ?
It is never correct. It will invoke undefined behavior whenever
sizeof(unsigned long) sizeof a or
size_t* has different size, representation, or passing mechanism
than unsigned long* or
size_t has different alignment that unsigned long.
If sizeof a sizeof(unsigned long) you merely get the wrong answer.
If none of the above, it might work.
Remove del for email
Jul 2 '08 #53

P: n/a
On Tue, 1 Jul 2008 09:56:08 -0700 (PDT), pereges <Br*****@gmail.com>
wrote:
>On Jul 1, 9:52 pm, Keith Thompson <ks...@mib.orgwrote:
>>
What range checks are you referring to?

Get the types right first, then worry about range checking.

I mean checking if the value of a variable is within some permissible
range eg. an int should always be between INT_MIN and INT_MAX range
Then use fgets and strtol or strtoul.
Remove del for email
Jul 2 '08 #54

P: n/a
On Jul 2, 11:13 am, Barry Schwarz <schwa...@dqel.comwrote:
Then use fgets and strtol or strtoul.
what about matherr ? It's avaiable on my implementation but it clearly
says "not standard C"
Jul 2 '08 #55

P: n/a
pereges wrote:
On Jul 2, 11:13 am, Barry Schwarz <schwa...@dqel.comwrote:
>Then use fgets and strtol or strtoul.

what about matherr ? It's avaiable on my implementation but it clearly
says "not standard C"
There's your answer then...

Bye, Jojo
Jul 2 '08 #56

P: n/a
Ok, I looked up the stroto* family of functions and have a question
with regards to that. What if I want to read a size_t variable from
the user and ensure that there is no overflow at the same time. eg:

size_t a;
char *ptr = NULL;
char *endptr;
char a_str[40]; /* User enters a string that we want to convert into a
size_t type variable */

puts("Enter the value of a\n");

if (fgets(a_str, 40, stdin) == NULL)
{
/* do the error handling */
}

if ((ptr = strchr(a_str, '\n') != NULL)
{
*ptr = '\0';
}

Now, I would like to change the string into a size_t type variable but
no strto* function allows it. Atmost I can convert to unsigned long
using strtoul function. If size_t is typedef as an unsigned long, then
there are no problems or else if its unsigned int it should overflow.
Is there any way out of this ? One way I can think of is to write a
seperate function for size_t and parse the string.

errno = 0;
a = strtoul(a_str, &endptr);

if (errno == ERANGE)
{
if (abs(a) == HUGE_VAL)
{
/* Overflow */
}
else
if (a == 0)
{
/* Underflow */
}
}
else
if (a == 0)
{
/* Conversion failed */
}

Jul 2 '08 #57

P: n/a
After conversion, if I check a against SIZE_MAX and SIZE_MIN..probably
that can help.
Jul 2 '08 #58

P: n/a
On Jul 2, 4:51 pm, pereges <Brol...@gmail.comwrote:
After conversion, if I check a against SIZE_MAX and SIZE_MIN..probably
that can help.
size_t is an unsigned integer. Unsigned integers all have the same
"MIN": 0.
You *DONT* have to check for < 0. The value cannot be less than 0.
The following types need not to be checked for < 0:

unsigned char
unsigned short
unsigned int
unsigned long
unsigned long long
size_t
uintptr_t
uintmax_t
uint8_t
uint16_t
uint32_t
uint64_t
uint_fast8_t
uint_fast16_t
uint_fast32_t
uint_fast64_t
time_t
clock_t

Maybe there are more unsigned integer types in the standard, I can not
recall.
Please, do not make another post about checking for < 0... Every time
you want to check a type for < 0 look at my post and find whether it
belongs to the list or not.
.... Another Cunningham?
Jul 2 '08 #59

P: n/a
On Jul 2, 7:02 pm, vipps...@gmail.com wrote:
On Jul 2, 4:51 pm, pereges <Brol...@gmail.comwrote:
After conversion, if I check a against SIZE_MAX and SIZE_MIN..probably
that can help.

size_t is an unsigned integer. Unsigned integers all have the same
"MIN": 0.
You *DONT* have to check for < 0. The value cannot be less than 0.
The following types need not to be checked for < 0:

unsigned char
unsigned short
unsigned int
unsigned long
unsigned long long
size_t
uintptr_t
uintmax_t
uint8_t
uint16_t
uint32_t
uint64_t
uint_fast8_t
uint_fast16_t
uint_fast32_t
uint_fast64_t
time_t
clock_t

Maybe there are more unsigned integer types in the standard, I can not
recall.
Please, do not make another post about checking for < 0... Every time
you want to check a type for < 0 look at my post and find whether it
belongs to the list or not.

... Another Cunningham?
Ok, sorry I realize I made a mistake. I tried to run the program and
it didn't work.
Jul 2 '08 #60

P: n/a
On Jul 2, 7:02 pm, vipps...@gmail.com wrote:
On Jul 2, 4:51 pm, pereges <Brol...@gmail.comwrote:
After conversion, if I check a against SIZE_MAX and SIZE_MIN..probably
that can help.

size_t is an unsigned integer. Unsigned integers all have the same
"MIN": 0.
You *DONT* have to check for < 0. The value cannot be less than 0.
The following types need not to be checked for < 0:

unsigned char
unsigned short
unsigned int
unsigned long
unsigned long long
size_t
uintptr_t
uintmax_t
uint8_t
uint16_t
uint32_t
uint64_t
uint_fast8_t
uint_fast16_t
uint_fast32_t
uint_fast64_t
time_t
clock_t

Maybe there are more unsigned integer types in the standard, I can not
recall.
Please, do not make another post about checking for < 0... Every time
you want to check a type for < 0 look at my post and find whether it
belongs to the list or not.

... Another Cunningham?

Ok, I'm sorry for my mistake. I forgot about it. Anyway here's my
program and there seems to be some problem :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <math.h>
#include <limits.h>

int main(void)
{
size_t a; /* size_t variable */
char a_str[50]; /* String to be converted */
char *ptr = NULL;
char *endptr;
unsigned long l;

if (fgets(a_str, 50, stdin) == NULL)
{
fprintf(stderr, "Error while entering the stirng\n");
return (1);
}

if ((ptr = strchr(a_str, '\n')) != NULL)
{
*ptr = '\0';
}

errno = 0;

l = strtoul(a_str, &endptr, 0); /* Convert string to long unsigned
first */

if (errno == ERANGE)
{
if (abs(l) == HUGE_VAL)
{
fprintf(stderr, "OVERFLOW\n");
return (1);
}
else
if (l == 0)
{
fprintf(stderr, "UNDERFLOW\n");
return (1);
}
}
else
{
if (l == 0.0)
{
fprintf(stderr, "Conversion failed\n");
return (1);
}
}

if (l <= UINT_MAX) /* On my TCC, size_t is typedefed as unsigned
int */
{
a = (size_t)l;
printf("\n%u", a);
}
else
printf("OVERFLOW");

return (0);
}
The program gives proper output until you enter a negative number for
which, ideally, it should print "UNDERFLOW" but it seems to print
"Conversion failed".
Jul 2 '08 #61

P: n/a
Ok, I'm sorry for my mistake. I forgot about it. Anyway here's my
program and there seems to be some problem :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <math.h>
#include <limits.h>

int main(void)
{
size_t a; /* size_t variable */
char a_str[50]; /* String to be converted */
char *ptr = NULL;
char *endptr;
unsigned long l;

if (fgets(a_str, 50, stdin) == NULL)
{
fprintf(stderr, "Error while entering the stirng\n");
return (1);
}

if ((ptr = strchr(a_str, '\n')) != NULL)
{
*ptr = '\0';
}

errno = 0;

l = strtoul(a_str, &endptr, 0); /* Convert string to long unsigned
first */

if (errno == ERANGE)
{
if (abs(l) == HUGE_VAL)
{
fprintf(stderr, "OVERFLOW\n");
return (1);
}
else
if (l == 0)
{
fprintf(stderr, "UNDERFLOW\n");
return (1);
}
}
else
{
if (l == 0.0)
{
fprintf(stderr, "Conversion failed\n");
return (1);
}
}

if (l <= UINT_MAX) /* On my TCC, size_t is typedefed as unsigned
int */
{
a = (size_t)l;
printf("\n%lu", (unsigned long)a);
}
else
printf("OVERFLOW");

return (0);

}

The program gives proper output until you enter a negative number for
which, ideally, it should print "UNDERFLOW" but it seems to print
"Conversion failed".
Jul 2 '08 #62

P: n/a
On Jul 2, 6:04 pm, pereges <Brol...@gmail.comwrote:
Ok, I'm sorry for my mistake. I forgot about it. Anyway here's my
program and there seems to be some problem :
<snip>
if (fgets(a_str, 50, stdin) == NULL)
{
fprintf(stderr, "Error while entering the stirng\n");
return (1);
return EXIT_FAILURE.
<snip>
l = strtoul(a_str, &endptr, 0); /* Convert string to long unsigned
first */
<snip>
The program gives proper output until you enter a negative number for
which, ideally, it should print "UNDERFLOW" but it seems to print
"Conversion failed".
strtoul() converts a string to unsigned long.
unsigned integers CANNOT have negative values.
See all my previous posts telling you this exact thing!
Jul 2 '08 #63

P: n/a
On Jul 2, 8:23 pm, vipps...@gmail.com wrote:
strtoul() converts a string to unsigned long.
unsigned integers CANNOT have negative values.
See all my previous posts telling you this exact thing!
Then how to detect unsigned integer underflow ?? or its not possible
with strtoul and it will simply report as "conversion failed"
Jul 2 '08 #64

P: n/a
pereges <Br*****@gmail.comwrites:
On Jul 2, 8:23 pm, vipps...@gmail.com wrote:
>strtoul() converts a string to unsigned long.
unsigned integers CANNOT have negative values.
See all my previous posts telling you this exact thing!

Then how to detect unsigned integer underflow ?? or its not possible
with strtoul and it will simply report as "conversion failed"
The point is that an input of "-36" is as meaningless as one of
"banana" when passed to strtoul. If you want, for some odd reason, to
accept a negative number and then check that it is positive you need
to use strtol, assign the result to a signed long, and compare that.
Seem like a waste of time, but you can do that it you like.

--
Ben.
Jul 2 '08 #65

P: n/a
pereges wrote:
On Jul 2, 8:23 pm, vipps...@gmail.com wrote:
>strtoul() converts a string to unsigned long.
unsigned integers CANNOT have negative values.
See all my previous posts telling you this exact thing!

Then how to detect unsigned integer underflow ?? or its not possible
with strtoul and it will simply report as "conversion failed"
Unsigned types don't underflow or overflow in C. Rather they "wrap
around". If you attempt to store a negative integer in an unsigned
object, what will actually be stored is a positive value determined
according to the properties of modular arithmetic.

<http://en.wikipedia.org/wiki/Modular_arithmetic>

So unsigned integers cannot, by definition, hold "wrong" values. If you
want, you can, in your program, check the numeric strings you operate
upon for the presence of a '-' prefix before attempting to convert them
to unsigned integers.

Jul 2 '08 #66

P: n/a
On Jul 2, 9:06 pm, Ben Bacarisse <ben.use...@bsb.me.ukwrote:
The point is that an input of "-36" is as meaningless as one of
"banana" when passed to strtoul. If you want, for some odd reason, to
accept a negative number and then check that it is positive you need
to use strtol, assign the result to a signed long, and compare that.
Seem like a waste of time, but you can do that it you like.
No, I guess that would over complicate things. I'm only interested in
taking a input from the user and checking if it is within the range of
representable values for a particular data type. I realized scanf is
somewhat dangerous in that regard.
Jul 2 '08 #67

P: n/a
On Jul 2, 9:08 pm, santosh <santosh....@gmail.comwrote:
Unsigned types don't underflow or overflow in C. Rather they "wrap
around". If you attempt to store a negative integer in an unsigned
object, what will actually be stored is a positive value determined
according to the properties of modular arithmetic.

<http://en.wikipedia.org/wiki/Modular_arithmetic>

So unsigned integers cannot, by definition, hold "wrong" values. If you
want, you can, in your program, check the numeric strings you operate
upon for the presence of a '-' prefix before attempting to convert them
to unsigned integers.
Yeah, I noticed that -1 becomes 65535(UINT_MAX). In that case I will
modify my program to :

l = strtoul(a_str, &endptr, 0); /* Convert string to long unsigned
first */

if (errno == ERANGE)
{
if (abs(l) == HUGE_VAL)
{
fprintf(stderr, "OUT OF RANGE OF REPRESENTABLE VALUES\n");
return (1);
}
}
else
{
if (l == 0)
{
fprintf(stderr, "CONVERSION OF STRING FAILED\n");
}
}
Jul 2 '08 #68

P: n/a
pereges <Br*****@gmail.comwrites:
After conversion, if I check a against SIZE_MAX and SIZE_MIN..probably
that can help.
As has already been pointed out, there is no SIZE_MIN; it's just 0.

I think that SIZE_MAX is new in C99. If so, you can use (size_t)-1,
which is guaranteed to be the largest value of type size_t.

In C90, size_t can't be any bigger than unsigned long, though it may
be smaller. You can use strtoul() to get an unsigned long value,
compare the result against SIZE_MAX, and assign it to a size_t object.
(Note: no cast is needed or recommended for this assignment.)

In C99, size_t can be bigger than unsigned long; it can even, in
theory, be bigger than unsigned long long. To be completely safe, you
can use strtoumax(). And for compatibility with both C90 and C99, you
can check the value of __STDC_VERSION__, writing separate code for C90
and C99.

It's likely that you don't need absolute 100% portability, and that
restricting yourself to values within the range of unsigned long is
good enough for your purposes; if so, you can write straight
C90-compatible code, at some small risk of rejecting valid size_t
values greater than 2**31-1 (more precisely, greater than ULONG_MAX).
In fact, the C99 standard recommends (but does not insist) that size_t
be no wider than unsigned long.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jul 2 '08 #69

P: n/a
pereges <Br*****@gmail.comwrites:
On Jul 2, 9:08 pm, santosh <santosh....@gmail.comwrote:
>Unsigned types don't underflow or overflow in C. Rather they "wrap
around". If you attempt to store a negative integer in an unsigned
object, what will actually be stored is a positive value determined
according to the properties of modular arithmetic.

<http://en.wikipedia.org/wiki/Modular_arithmetic>

So unsigned integers cannot, by definition, hold "wrong" values. If you
want, you can, in your program, check the numeric strings you operate
upon for the presence of a '-' prefix before attempting to convert them
to unsigned integers.

Yeah, I noticed that -1 becomes 65535(UINT_MAX). In that case I will
modify my program to :

l = strtoul(a_str, &endptr, 0); /* Convert string to long unsigned
first */

if (errno == ERANGE)
{
if (abs(l) == HUGE_VAL)
{
fprintf(stderr, "OUT OF RANGE OF REPRESENTABLE VALUES\n");
return (1);
}
}
strtoul does not generate HUGE_VAL (that is a double value). Also
this logic looks odd..
else
{
if (l == 0)
{
fprintf(stderr, "CONVERSION OF STRING FAILED\n");
}
}
--
Ben.
Jul 2 '08 #70

P: n/a
On Jul 3, 1:28 am, Ben Bacarisse <ben.use...@bsb.me.ukwrote:
strtoul does not generate HUGE_VAL (that is a double value). Also
this logic looks odd..
ok

else
{
if (l == 0)
{
fprintf(stderr, "CONVERSION OF STRING FAILED\n");
}
Yes it does look odd because that would mean conversion of strings
like "0" would also fail. But this what I found on one reference site
about strtoul :

"
On success, the function returns the converted integral number as a
long int value.
If no valid conversion could be performed, a zero value is returned.
If the correct value is out of the range of representable values,
ULONG_MAX is returned, an the global variable errno is set to ERANGE"

Note the bit where it says "If no valid conversion could be performed
0 is returned. And yeah, instead of HUGE_VAL it should be ULONG_MAX
Jul 2 '08 #71

P: n/a
btw i want to read a string containing 3 numbers:

"1234 3333 6666"

SO the logic I used was
unsigned long l1, l2, l3;
char s[] = "1234 3333 6666"
char *endptr1, *endptr2

errno = 0;

l1 = strtoul(s, &endptr1, 10);
l2 = strtoul(&endptr1, &endptr2, 10);
l3 = strtoul(&endptr2, NULL, ), 10);

if (errno == ERANGE)
{
if (l1 == ULONG_MAX || l2 == ULONG_MAX || l3 == ULONG_MAX)
{
/* do the error handling */
}
}
else
{
if (s == endptr1 || endptr1 == endptr2)
{
printf("Conversion failed");
return (1);
}
}
Jul 2 '08 #72

P: n/a
pereges <Br*****@gmail.comwrites:
On Jul 3, 1:28 am, Ben Bacarisse <ben.use...@bsb.me.ukwrote:
>strtoul does not generate HUGE_VAL (that is a double value). Also
this logic looks odd..

ok
else
{
if (l == 0)
{
fprintf(stderr, "CONVERSION OF STRING FAILED\n");
}

Yes it does look odd because that would mean conversion of strings
like "0" would also fail.
Exactly, though i was also talking about the if part as well. You
had (corrected to avoid HUGE_VAL)

if (errno == ERANGE) {
if (l == ULONG_MAX)
fprintf(...);
}

I'll say what I'd do below...
But this what I found on one reference site
about strtoul :

"
On success, the function returns the converted integral number as a
long int value.
If no valid conversion could be performed, a zero value is returned.
If the correct value is out of the range of representable values,
ULONG_MAX is returned, an the global variable errno is set to ERANGE"

Note the bit where it says "If no valid conversion could be performed
0 is returned. And yeah, instead of HUGE_VAL it should be ULONG_MAX
And it is correct, but that does not mean that a return of zero means
no conversion could be performed (it's and "if" not an "if and only
if").

I think you are making this too complex. Only two things can go wrong
with strtoul and they are easy to test for. If no conversion has been
done, then the end pointer is set to the initial pointer passed. If a
range error occurs, errno is set and ULONG_MAX is returned:

unsigned long l;
char *ep;
errno = 0;
if ((l = strtoul(num, &ep, 10)) == ULONG_MAX && errno == ERANGE)
fprintf(stderr, "Number out of range.\n");
else if (ep == num)
fprintf(stderr, "Invalid number (not converted).\n");

--
Ben.
Jul 2 '08 #73

P: n/a
btw i want to read a string containing 3 numbers:

"1234 3333 6666"

SO the logic I used was

unsigned long l1, l2, l3;
char s[] = "1234 3333 6666";
char *endptr1, *endptr2, *endptr3;

errno = 0;

l1 = strtoul(s, &endptr1, 10);
l2 = strtoul(&endptr1, &endptr2, 10);
l3 = strtoul(&endptr2, &endptr3, 10);

if (errno == ERANGE)
{
if (l1 == ULONG_MAX || l2 == ULONG_MAX || l3 == ULONG_MAX)
{
/* do the error handling */
}
}

else
{
if (s == endptr1 || endptr1 == endptr2 || endptr2 == endptr3)
{
printf("Conversion failed");
return (1);
}
}
Jul 2 '08 #74

P: n/a
pereges <Br*****@gmail.comwrites:
btw i want to read a string containing 3 numbers:

"1234 3333 6666"

SO the logic I used was
unsigned long l1, l2, l3;
char s[] = "1234 3333 6666"
char *endptr1, *endptr2

errno = 0;

l1 = strtoul(s, &endptr1, 10);
l2 = strtoul(&endptr1, &endptr2, 10);
^ no & needed.
l3 = strtoul(&endptr2, NULL, ), 10);
^ ditto.

Ah, no. You really need to keep the last end pointer as well and
errno can get reset, so this just does not work. The following might
work (but it's late so don't be surprised if this is not right):

bool too_big = false;
errno = 0;
l1 = strtoul(s, &endptr1, 10);
too_big |= l1 == ULONG_MAX && errno == ERANGE;
errno = 0;
l2 = strtoul(endptr1, &endptr2, 10);
too_big |= l2 == ULONG_MAX && errno == ERANGE;
errno = 0;
l3 = strtoul(endptr2, &endptr3, 10);
too_big |= l3 == ULONG_MAX && errno == ERANGE;

if (too_big)
....
else if (s == ensptr1 || endptr1 == endptr2 || endptr2 == endptr3)
...

but it might be worth writing a function to wrap strtoul that includes
the error messages that you want.

--
Ben.
Jul 2 '08 #75

P: n/a
pereges <Br*****@gmail.comwrites:
btw i want to read a string containing 3 numbers:
<snip>
SO the logic I used was

unsigned long l1, l2, l3;
char s[] = "1234 3333 6666";
char *endptr1, *endptr2, *endptr3;
OK, see may other reply but ignore the comment about needing endptr3.

<snip>

--
Ben.
Jul 2 '08 #76

P: n/a
On Jul 3, 2:29 am, Ben Bacarisse <ben.use...@bsb.me.ukwrote:
pereges <Brol...@gmail.comwrites:
btw i want to read a string containing 3 numbers:
"1234 3333 6666"
SO the logic I used was
unsigned long l1, l2, l3;
char s[] = "1234 3333 6666"
char *endptr1, *endptr2
errno = 0;
l1 = strtoul(s, &endptr1, 10);
l2 = strtoul(&endptr1, &endptr2, 10);

^ no & needed.l3 = strtoul(&endptr2, NULL, ), 10);

^ ditto.

Ah, no. You really need to keep the last end pointer as well and
errno can get reset, so this just does not work. The following might
work (but it's late so don't be surprised if this is not right):

bool too_big = false;
errno = 0;
l1 = strtoul(s, &endptr1, 10);
too_big |= l1 == ULONG_MAX && errno == ERANGE;
errno = 0;
l2 = strtoul(endptr1, &endptr2, 10);
too_big |= l2 == ULONG_MAX && errno == ERANGE;
errno = 0;
l3 = strtoul(endptr2, &endptr3, 10);
too_big |= l3 == ULONG_MAX && errno == ERANGE;

if (too_big)
....
else if (s == ensptr1 || endptr1 == endptr2 || endptr2 == endptr3)
...

but it might be worth writing a function to wrap strtoul that includes
the error messages that you want.
Why & is not needed ? The format of the function itself has a double
pointer to a char :

unsigned long int strtoul ( const char * str, char ** endptr, int
base );
Jul 2 '08 #77

P: n/a
^^Sorry for that dumb question. Its too late here too (:-

Jul 2 '08 #78

P: n/a
Thanks, it runs perfectly.

Btw A |= B & C is the same as A = A || (B & C) isn't it ?
Jul 2 '08 #79

P: n/a
pereges <Br*****@gmail.comwrites:
Thanks, it runs perfectly.

Btw A |= B & C is the same as A = A || (B & C) isn't it ?
No, because || is a short-circuit operator. It is the same as A = A |
(B & C).

It might be fine in this situation since once you have an input error
(in A) there may be no point in doing more, so the short-circuit
evaluation may be OK for this usage.

--
Ben.
Jul 3 '08 #80

P: n/a
pereges said:
Thanks, it runs perfectly.

Btw A |= B & C is the same as A = A || (B & C) isn't it ?
No. Consider A = 42, B = 21, C = 15.

B & C is 5, and A |= 5 gives 47.

But 42 || 5 is simply 1, so the second expression gives A a value of 1.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jul 3 '08 #81

P: n/a
On Wed, 2 Jul 2008 06:44:04 -0700 (PDT), pereges <Br*****@gmail.com>
wrote:
>Ok, I looked up the stroto* family of functions and have a question
with regards to that. What if I want to read a size_t variable from
the user and ensure that there is no overflow at the same time. eg:

size_t a;
char *ptr = NULL;
char *endptr;
char a_str[40]; /* User enters a string that we want to convert into a
size_t type variable */

puts("Enter the value of a\n");

if (fgets(a_str, 40, stdin) == NULL)
{
/* do the error handling */
}

if ((ptr = strchr(a_str, '\n') != NULL)
{
*ptr = '\0';
}

Now, I would like to change the string into a size_t type variable but
no strto* function allows it. Atmost I can convert to unsigned long
using strtoul function. If size_t is typedef as an unsigned long, then
there are no problems or else if its unsigned int it should overflow.
Is there any way out of this ? One way I can think of is to write a
seperate function for size_t and parse the string.

errno = 0;
a = strtoul(a_str, &endptr);

if (errno == ERANGE)
If SIZE_MAX < ULONG_MAX, this test is unreliable. For all values
between SIZE_MAX+1 and ULONG_MAX, errno will not be set but a will
contain the wrong value.
>{
if (abs(a) == HUGE_VAL)
a is guaranteed to be non-negative so using abs() buys you nothing.
{
/* Overflow */
}
else
if (a == 0)
{
/* Underflow */
Since errno is set to ERANGE, you are guaranteed that a will not be
zero.
}
}
else
if (a == 0)
{
/* Conversion failed */
Except in the case where the user entered 0. You should be checking
endptr for conversion failures.
}
If you really are concerned about exceeding the range of size_t, check
you compiler's documentation or limits.h for the type with the
greatest ??_MAX value. Use the corresponding strtou?? function to
convert the input to a value of that type. Then compare the value
against SIZE_MAX.

In the (rare) case where size_t is a typedef for this "maximum" type,
you could set the units digit (endptr will tell you where it is) to
'\0', execute the strtou?? function and check against ??_MAX/10.
Remove del for email
Jul 3 '08 #82

P: n/a
On Wed, 2 Jul 2008 08:01:44 -0700 (PDT), pereges <Br*****@gmail.com>
wrote:
>On Jul 2, 7:02 pm, vipps...@gmail.com wrote:
>On Jul 2, 4:51 pm, pereges <Brol...@gmail.comwrote:
After conversion, if I check a against SIZE_MAX and SIZE_MIN..probably
that can help.

size_t is an unsigned integer. Unsigned integers all have the same
"MIN": 0.
You *DONT* have to check for < 0. The value cannot be less than 0.
The following types need not to be checked for < 0:

unsigned char
unsigned short
unsigned int
unsigned long
unsigned long long
size_t
uintptr_t
uintmax_t
uint8_t
uint16_t
uint32_t
uint64_t
uint_fast8_t
uint_fast16_t
uint_fast32_t
uint_fast64_t
time_t
clock_t

Maybe there are more unsigned integer types in the standard, I can not
recall.
Please, do not make another post about checking for < 0... Every time
you want to check a type for < 0 look at my post and find whether it
belongs to the list or not.

... Another Cunningham?


Ok, I'm sorry for my mistake. I forgot about it. Anyway here's my
program and there seems to be some problem :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <math.h>
#include <limits.h>

int main(void)
{
size_t a; /* size_t variable */
char a_str[50]; /* String to be converted */
char *ptr = NULL;
char *endptr;
unsigned long l;

if (fgets(a_str, 50, stdin) == NULL)
{
fprintf(stderr, "Error while entering the stirng\n");
return (1);
}

if ((ptr = strchr(a_str, '\n')) != NULL)
{
*ptr = '\0';
}

errno = 0;

l = strtoul(a_str, &endptr, 0); /* Convert string to long unsigned
first */
Better to use 10 unless you really want a leading zero to mean octal.
>
if (errno == ERANGE)
{
if (abs(l) == HUGE_VAL)
Why do you keep taking the absolute value of a value that cannot be
negative?

HUGE_VAL is a double. It is not the value returned by strtoul when
errno is set to ERANGE. That honor belongs to ULONG_MAX.
{
fprintf(stderr, "OVERFLOW\n");
return (1);
}
else
if (l == 0)
If errno is set to ERANGE, l cannot be zero.
{
fprintf(stderr, "UNDERFLOW\n");
return (1);
}
}
else
{
if (l == 0.0)
l is an unsigned long. Why force conversion to double when 0 will do
the job just as well?
{
fprintf(stderr, "Conversion failed\n");
return (1);
}
}

if (l <= UINT_MAX) /* On my TCC, size_t is typedefed as unsigned
int */
SIZE_MAX would be better if you have it.
{
a = (size_t)l;
The cast is unnecessary (unless its **only** purpose is to silence a
warning about converting to a shorter type).
printf("\n%u", a);
For portability (you are asking people with other systems for help),
you should cast a to unsigned int.
}
else
printf("OVERFLOW");
Was it a deliberate decision to not differentiate between strtoul
overflow and size_t overflow?
>
return (0);
}
The program gives proper output until you enter a negative number for
which, ideally, it should print "UNDERFLOW" but it seems to print
No it should not.
>"Conversion failed".
On my system it prints the value of the negative number converted to
unsigned int.
Remove del for email
Jul 3 '08 #83

P: n/a
On Wed, 2 Jul 2008 08:04:48 -0700 (PDT), pereges <Br*****@gmail.com>
wrote:
>Ok, I'm sorry for my mistake. I forgot about it. Anyway here's my
program and there seems to be some problem :
snip 70 lines of previously posted code
>
The program gives proper output until you enter a negative number for
which, ideally, it should print "UNDERFLOW" but it seems to print
"Conversion failed".
Posting the same program repeatedly without digesting the comments
does not constitute progress.
Remove del for email
Jul 3 '08 #84

P: n/a
On Wed, 2 Jul 2008 08:48:00 -0700 (PDT), pereges <Br*****@gmail.com>
wrote:
>On Jul 2, 8:23 pm, vipps...@gmail.com wrote:
>strtoul() converts a string to unsigned long.
unsigned integers CANNOT have negative values.
See all my previous posts telling you this exact thing!

Then how to detect unsigned integer underflow ?? or its not possible
with strtoul and it will simply report as "conversion failed"
Check the input string for a '-'.
Remove del for email
Jul 3 '08 #85

P: n/a
On Wed, 2 Jul 2008 13:35:10 -0700 (PDT), pereges <Br*****@gmail.com>
wrote:
>On Jul 3, 1:28 am, Ben Bacarisse <ben.use...@bsb.me.ukwrote:
>strtoul does not generate HUGE_VAL (that is a double value). Also
this logic looks odd..

ok

else
{
if (l == 0)
{
fprintf(stderr, "CONVERSION OF STRING FAILED\n");
}

Yes it does look odd because that would mean conversion of strings
like "0" would also fail. But this what I found on one reference site
about strtoul :
Proof positive that you should not accept internet musings as gospel.
>
"
On success, the function returns the converted integral number as a
long int value.
Strange, doesn't the u in the function name mean unsigned?
>If no valid conversion could be performed, a zero value is returned.
This only occurs if the string is empty or the first non-white space
character is not acceptable to the number base.
>If the correct value is out of the range of representable values,
ULONG_MAX is returned, an the global variable errno is set to ERANGE"
So why were you using HUGE_VAL?
>
Note the bit where it says "If no valid conversion could be performed
0 is returned. And yeah, instead of HUGE_VAL it should be ULONG_MAX
Note the bit that says the converted value has to be out of range. -1
converted to unsigned long is in range.
Remove del for email
Jul 3 '08 #86

P: n/a
On Wed, 2 Jul 2008 14:06:48 -0700 (PDT), pereges <Br*****@gmail.com>
wrote:
>btw i want to read a string containing 3 numbers:

"1234 3333 6666"

SO the logic I used was
unsigned long l1, l2, l3;
char s[] = "1234 3333 6666"
char *endptr1, *endptr2

errno = 0;

l1 = strtoul(s, &endptr1, 10);
l2 = strtoul(&endptr1, &endptr2, 10);
Didn't your compiler generate a mandatory diagnostic here. The first
argument to strtoul must be a char*. &endptr1 is a char**. The types
are incompatible.
>l3 = strtoul(&endptr2, NULL, ), 10);
You don't care if strtoul found an invalid character while attempting
to convert the third number?
>
if (errno == ERANGE)
{
if (l1 == ULONG_MAX || l2 == ULONG_MAX || l3 == ULONG_MAX)
Do you think this can ever evaluate to false?
{
/* do the error handling */
}
}
else
{
if (s == endptr1 || endptr1 == endptr2)
There are other failure possibilities (1234 5678 9abc).
{
printf("Conversion failed");
return (1);
Use EXIT_FAILURE if you want help from people for whom 1 is not an
appropriate value to return from main.
}
}

Remove del for email
Jul 3 '08 #87

P: n/a
On Wed, 02 Jul 2008 22:29:19 +0100, Ben Bacarisse
<be********@bsb.me.ukwrote:
>pereges <Br*****@gmail.comwrites:
>btw i want to read a string containing 3 numbers:

"1234 3333 6666"

SO the logic I used was
unsigned long l1, l2, l3;
char s[] = "1234 3333 6666"
char *endptr1, *endptr2

errno = 0;

l1 = strtoul(s, &endptr1, 10);
l2 = strtoul(&endptr1, &endptr2, 10);
^ no & needed.
>l3 = strtoul(&endptr2, NULL, ), 10);
^ ditto.

Ah, no. You really need to keep the last end pointer as well and
errno can get reset, so this just does not work. The following might
No library function is allowed to reset errno (7.5-3).
>work (but it's late so don't be surprised if this is not right):

bool too_big = false;
errno = 0;
l1 = strtoul(s, &endptr1, 10);
too_big |= l1 == ULONG_MAX && errno == ERANGE;
errno = 0;
l2 = strtoul(endptr1, &endptr2, 10);
too_big |= l2 == ULONG_MAX && errno == ERANGE;
errno = 0;
l3 = strtoul(endptr2, &endptr3, 10);
too_big |= l3 == ULONG_MAX && errno == ERANGE;

if (too_big)
....
else if (s == ensptr1 || endptr1 == endptr2 || endptr2 == endptr3)
...

but it might be worth writing a function to wrap strtoul that includes
the error messages that you want.

Remove del for email
Jul 3 '08 #88

P: n/a
On Wed, 2 Jul 2008 14:10:23 -0700 (PDT), pereges <Br*****@gmail.com>
wrote:
>btw i want to read a string containing 3 numbers:
You seem to be having a problem with double postings.
Remove del for email
Jul 3 '08 #89

P: n/a
pereges wrote:
On Jul 2, 9:06 pm, Ben Bacarisse <ben.use...@bsb.me.ukwrote:
>The point is that an input of "-36" is as meaningless as one of
"banana" when passed to strtoul. If you want, for some odd reason,
to accept a negative number and then check that it is positive you
need to use strtol, assign the result to a signed long, and compare
that. Seem like a waste of time, but you can do that it you like.

No, I guess that would over complicate things. I'm only interested in
taking a input from the user and checking if it is within the range of
representable values for a particular data type. I realized scanf is
somewhat dangerous in that regard.
The strto* set of functions should be sufficient. In addition you can
always scan the input string yourself before conversion for additional
checks and restrictions. The ato* and *scanf set of function produce
undefined behaviour on overflow, and thus are a far less suitable
choice for string to numeric conversions.

Jul 3 '08 #90

P: n/a
Barry Schwarz <sc******@dqel.comwrites:
On Wed, 02 Jul 2008 22:29:19 +0100, Ben Bacarisse
<be********@bsb.me.ukwrote:
>>pereges <Br*****@gmail.comwrites:
>>btw i want to read a string containing 3 numbers:

"1234 3333 6666"

SO the logic I used was
unsigned long l1, l2, l3;
char s[] = "1234 3333 6666"
char *endptr1, *endptr2

errno = 0;

l1 = strtoul(s, &endptr1, 10);
l2 = strtoul(&endptr1, &endptr2, 10);
^ no & needed.
>>l3 = strtoul(&endptr2, NULL, ), 10);
^ ditto.

Ah, no. You really need to keep the last end pointer as well and
errno can get reset, so this just does not work. The following might

No library function is allowed to reset errno (7.5-3).
That is not what was worrying me about the code. I did not mean
"reset to zero" -- I was worried that it would get set to some other
value that is not tested for thereby missing an error that the code
*did* want to catch. Reset was a bad word since it impiles "to zero".

In fact, strtoul never sets it to anything but one value so there is
no problem there. I suppose I could argue that one can't be sure that
a future standard will permit strtoul to set it to some other value
(or to ERANGE in some new situations) but that seems to be stretching
the point. Good catch.

Pereges: you can revert to the simpler test you had

if (errno == ERANGE && (l1 == ULONG_MAX || l2 == ... etc))

strtoul is not permitted to set errno to anything but ERANGE and it is
only permitted to do that when it returns ULONG_MAX so you can safely
test all three cases on one go.

--
Ben.
Jul 3 '08 #91

P: n/a
I wrote a function for converting a string of doubles of the form
"xxxxxx yyyyyy zzzzz" into three seperate doubles. Can some one please
tell me if I done something wrong here ?

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <math.h>
#include <string.h>

int string_to_double(char *s, char **endptr, double *f)
{
int too_big = 0;

errno = 0;

*f = strtod(s, endptr);
too_big = (errno == ERANGE);

if (too_big)
{
fprintf(stderr, "OUT OF RANGE OF REPRESENTABLE VALUES
\n");
return (1);
}
else
{
if (s == *endptr)
{
fprintf(stderr, "CONVERSION OF STRING FAILED
\n");
return (1);
}
}

return (0);
}
int main(void)
{
char s[50], *ptr = NULL;
char *endptr1, *endptr2, *endptr3;
double f1, f2, f3;
int rc;

if (fgets(s, 50, stdin) == NULL)
{
fprintf(stderr, "ERROR IN INPUT STRING\n");
return (1);
}
if ((ptr = strchr(s, '\n')) != NULL)
{
*ptr = '\0';
}

rc = (string_to_double(s, &endptr1, &f1) == 0) &&
(string_to_double(endptr1, &endptr2, &f2) == 0) &&
(string_to_double(endptr2, &endptr3, &f3) == 0);
if (rc == 1)
{
printf("%f %f %f\n", f1, f2, f3);
}

return (!rc);
}
Jul 3 '08 #92

P: n/a
I think for unsigned long and size_t, the check for '-' or any
anything other than a digit or white space is easy. This can be
achieved by simply parsing the string before passing it on to strtoul.

while (s[i] != '\0')
{
if (isdigit(s[i]) || isspace(s[i]))
{
i++;
}
else
/* do error handling */
}

With this, the problem when there are some characters in the string is
also eliminated and the function can be terminated quite early. For a
double, its a lot more difficult because there can be too many cases
and its probably not worth it but one can implement some simple things
like checking for alphabets other than 'e'.
Jul 3 '08 #93

P: n/a
pereges wrote:
I wrote a function for converting a string of doubles of the form
"xxxxxx yyyyyy zzzzz" into three seperate doubles. Can some one please
tell me if I done something wrong here ?

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <math.h>
#include <string.h>

int string_to_double(char *s, char **endptr, double *f)
{
int too_big = 0;

errno = 0;

*f = strtod(s, endptr);
too_big = (errno == ERANGE);

if (too_big)
{
fprintf(stderr, "OUT OF RANGE OF REPRESENTABLE VALUES
\n");
return (1);
}
else
{
if (s == *endptr)
{
fprintf(stderr, "CONVERSION OF STRING FAILED
\n");
return (1);
}
}

return (0);
}
int main(void)
{
char s[50], *ptr = NULL;
char *endptr1, *endptr2, *endptr3;
double f1, f2, f3;
int rc;

if (fgets(s, 50, stdin) == NULL)
{
fprintf(stderr, "ERROR IN INPUT STRING\n");
return (1);
Use EXIT_FAILURE instead of 1.
}
if ((ptr = strchr(s, '\n')) != NULL)
{
*ptr = '\0';
}
This isn't necessary.
rc = (string_to_double(s, &endptr1, &f1) == 0) &&
(string_to_double(endptr1, &endptr2, &f2) == 0) &&
(string_to_double(endptr2, &endptr3, &f3) == 0);
if (rc == 1)
{
printf("%f %f %f\n", f1, f2, f3);
}

return (!rc);
}
Other than what I noted, the code is, as far as I can tell, correct and
ought to work for the type of input you described.

Jul 3 '08 #94

P: n/a
pereges wrote:
I think for unsigned long and size_t, the check for '-' or any
anything other than a digit or white space is easy. This can be
achieved by simply parsing the string before passing it on to strtoul.

while (s[i] != '\0')
{
if (isdigit(s[i]) || isspace(s[i]))
{
i++;
}
else
/* do error handling */
}
You will probably want to allow a '+' prefix though. Also use isxdigit
for hexadecimal strings and check octal strings for numeric characters
beyond seven.
<snip>

Jul 3 '08 #95

P: n/a
On Jul 4, 12:10 am, santosh <santosh....@gmail.comwrote:

<snip>
Use EXIT_FAILURE instead of 1.
I usually written 1 form any function (including main) when an error
occured and 0 when no error occurs. I have heard this is not protable.
If that's the case , then I will change this habit. (for main i.e.)
<snip>
This isn't necessary.
Why ? What about the last character ?
Jul 3 '08 #96

P: n/a
pereges wrote:
On Jul 4, 12:10 am, santosh <santosh....@gmail.comwrote:

<snip>
>Use EXIT_FAILURE instead of 1.

I usually written 1 form any function (including main) when an error
occured and 0 when no error occurs. I have heard this is not protable.
If that's the case , then I will change this habit. (for main i.e.)
One is not a portable return value from main. The portable values are 0,
EXIT_SUCCESS and EXIT_FAILURE. Other values are implementation defined.
<snip>
[context: about replacing the '\n' with '\0' before feeding a line to
strto*]
>This isn't necessary.

Why ? What about the last character ?
Conversion will stop at the first character that cannot be converted.
You can check *endptr for either '\0' or '\n' in this case (addition to
checking errno for ERANGE).

Jul 3 '08 #97

P: n/a
On Thu, 3 Jul 2008 05:42:10 -0700 (PDT), pereges <Br*****@gmail.com>
wrote:
>I wrote a function for converting a string of doubles of the form
"xxxxxx yyyyyy zzzzz" into three seperate doubles. Can some one please
tell me if I done something wrong here ?
Why didn't you just execute it and confirm it is broken?

Your first mistake was posting this in your thread about unsigned
long. You couldn't use a descriptive title?
>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <math.h>
And you use this header for?
>#include <string.h>
Ditto.
>
int string_to_double(char *s, char **endptr, double *f)
{
int too_big = 0;

errno = 0;

*f = strtod(s, endptr);
too_big = (errno == ERANGE);

if (too_big)
{
fprintf(stderr, "OUT OF RANGE OF REPRESENTABLE VALUES
\n");
return (1);
}
else
{
if (s == *endptr)
{
fprintf(stderr, "CONVERSION OF STRING FAILED
\n");
return (1);
}
}

return (0);
}
int main(void)
{
char s[50], *ptr = NULL;
char *endptr1, *endptr2, *endptr3;
double f1, f2, f3;
int rc;

if (fgets(s, 50, stdin) == NULL)
{
fprintf(stderr, "ERROR IN INPUT STRING\n");
return (1);
}
if ((ptr = strchr(s, '\n')) != NULL)
{
*ptr = '\0';
}

rc = (string_to_double(s, &endptr1, &f1) == 0) &&
(string_to_double(endptr1, &endptr2, &f2) == 0) &&
(string_to_double(endptr2, &endptr3, &f3) == 0);
You probably meant to use || here. If the first call succeeds, the
return value is 0. Since && is short-circuit operator, rc will be 0
and no more calls will be made. However, ...
>

if (rc == 1)
....the only way rc can be 1 is if all three function calls fail and
then of course you probably don't want to print out the values. I
think you need to reverse the return value from string_to_doubles.
{
printf("%f %f %f\n", f1, f2, f3);
}

return (!rc);
}

Remove del for email
Jul 4 '08 #98

P: n/a
On Thu, 3 Jul 2008 13:36:32 -0700 (PDT), pereges <Br*****@gmail.com>
wrote:
>On Jul 4, 12:10 am, santosh <santosh....@gmail.comwrote:

<snip>
>Use EXIT_FAILURE instead of 1.

I usually written 1 form any function (including main) when an error
occured and 0 when no error occurs. I have heard this is not protable.
If that's the case , then I will change this habit. (for main i.e.)
<snip>
>This isn't necessary.

Why ? What about the last character ?
Why isn't what necessary? Don't you think it would be better to leave
a little context?

The issue at hand is replacing the '\n' from fgets with a '\0'. The
reason it is not necessary is that either character will cause strto??
to terminate its conversion at that point.

Unless you check the character endptr is pointing to, the replacement
buys you nothing. And even if you do check, you can check for both
characters with less code and in less CPU time without the
replacement.
Remove del for email
Jul 4 '08 #99

P: n/a
On Wed, 02 Jul 2008 17:06:49 +0100, Ben Bacarisse
<be********@bsb.me.ukwrote:
pereges <Br*****@gmail.comwrites:
On Jul 2, 8:23 pm, vipps...@gmail.com wrote:
strtoul() converts a string to unsigned long.
unsigned integers CANNOT have negative values.
See all my previous posts telling you this exact thing!
Then how to detect unsigned integer underflow ?? or its not possible
with strtoul and it will simply report as "conversion failed"

The point is that an input of "-36" is as meaningless as one of
"banana" when passed to strtoul. If you want, for some odd reason, to
accept a negative number and then check that it is positive you need
to use strtol, assign the result to a signed long, and compare that.
Seem like a waste of time, but you can do that it you like.
A negative _value_ is meaningless for an unsigned (integer) type, but
for arguably unfortunate historical reasons strtoul, plus strtoull and
strtoumax in C99, actually accept _input_ beginning with a minus sign
and return the value negated using unsigned arithmetic.
(Which is, as frequently discussed, modulo 2 up nbits.)
(As I see in another thread you have already discovered.)

As suggested elsethread, you can (pre)parse the string yourself to
check for this, and give an error or whatever, if you want.

Conversion to a signed integer type of an integer value out of range
is implementation-defined, and in C99 (explicitly) may raise a signal.
On _most_ implementations, for a signed/unsigned pair of types, half
the range of the unsigned type is out of range for the signed type.

If you really want to accept a _signed_ (possibly but not necessarily
negative) number, strol (or ll or max) is usually the right way. If
you verify that the value is nonnegative, you can then (guaranteed)
convert it to the corresponding signed type without loss of
information. If negative, or in a larger/higher-rank type and
(actually) out of range, you can still convert to unsigned _safely_,
without any impl-def or undefined behavior, but with loss of info.

- formerly david.thompson1 || achar(64) || worldnet.att.net
Jul 14 '08 #100

105 Replies

This discussion thread is closed

Replies have been disabled for this discussion.