Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > string to int

Reply
Thread Tools

string to int

 
 
arnuld
Guest
Posts: n/a
 
      04-11-2012
I know we strtol() converts to long but I want to convert to an int. atoi
() does not detect errors so I don't think its advised to use it. I am
using strtol() anyway but putting check for INT_MAX and INT_MIN values. I
can not check for overflow/underflow because INT_MIN,MAX and LONG_MIN,MAX
have same values on my system. Can someone check of this behaves
correctly ?


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


enum { VAL_SUCC = 0,
VAL_ERR = -1
};

int str_to_int(const char* , int* );

int main(void)
{
const char* x = "-2147483648";
int i = 0;

printf(" i = %d, x = %s\n", i, x);
if( 0 > str_to_int(x, &i))
{
printf("IN: %s @%d: ERROR in Conversion :%s\n", __func__, __LINE__,
__FILE__);
}
printf(" i = %d, x = %s\n", i, x);
printf("INT_MAX = %d\n", INT_MAX);
printf("LONG_MAX = %ld\n", LONG_MAX);
printf("LONG_MIN = %ld\n", LONG_MIN);

return 0;
}


int str_to_int(const char* str, int* ip)
{
char *endptr;
long val;
int ret;

errno = 0; /* To distinguish success/failure after call */
val = strtol(str, &endptr, 10);

/* Check for various possible errors */
if ((ERANGE == errno && (LONG_MAX == val || LONG_MIN == val)) ||
((0 != errno) && (0 == val)))
{
perror("strtol");
ret = -1;
}
else if(endptr == str)
{
fprintf(stderr, "No digits were found\n");
ret = -1;
}
else /* If we got here, strtol() successfully parsed a number */
{
printf("strtol() returned %ld\n", val);
if ('\0' != *endptr) /* Not necessarily an error... */
{
printf("Further characters after number: %s\n", endptr);
}

if(INT_MAX < val || INT_MIN > val)
{
printf("IN: Value is greater/lower than what int can handle.
Can not represent it in an integer\n");
ret = -1;
}
else
{
*ip = val;
ret = 0;
}
}

return ret;
}

=========================== OUTPUT ===========================
~/programs/C $ ./a.out
i = 0, x = -2147483648
strtol() returned -2147483648
i = -2147483648, x = -2147483648
INT_MAX = 2147483647
LONG_MAX = 2147483647
LONG_MIN = -2147483648
~/programs/C $





--
arnuld
http://LispMachine.Wordpress.com
 
Reply With Quote
 
 
 
 
Barry Schwarz
Guest
Posts: n/a
 
      04-11-2012
On 11 Apr 2012 11:22:40 GMT, arnuld <(E-Mail Removed)> wrote:

>I know we strtol() converts to long but I want to convert to an int. atoi
>() does not detect errors so I don't think its advised to use it. I am
>using strtol() anyway but putting check for INT_MAX and INT_MIN values. I
>can not check for overflow/underflow because INT_MIN,MAX and LONG_MIN,MAX
>have same values on my system. Can someone check of this behaves
>correctly ?
>
>
>#include <stdio.h>
>#include <stdlib.h>
>#include <string.h>
>#include <errno.h>
>#include <limits.h>
>
>
>enum { VAL_SUCC = 0,
> VAL_ERR = -1
>};
>
>int str_to_int(const char* , int* );
>
>int main(void)
>{
> const char* x = "-2147483648";
> int i = 0;
>
> printf(" i = %d, x = %s\n", i, x);
> if( 0 > str_to_int(x, &i))
> {
> printf("IN: %s @%d: ERROR in Conversion :%s\n", __func__, __LINE__,
>__FILE__);
> }
> printf(" i = %d, x = %s\n", i, x);
> printf("INT_MAX = %d\n", INT_MAX);
> printf("LONG_MAX = %ld\n", LONG_MAX);
> printf("LONG_MIN = %ld\n", LONG_MIN);
>
> return 0;
>}
>
>
>int str_to_int(const char* str, int* ip)
>{
> char *endptr;
> long val;
> int ret;
>
> errno = 0; /* To distinguish success/failure after call */
> val = strtol(str, &endptr, 10);
>
> /* Check for various possible errors */
> if ((ERANGE == errno && (LONG_MAX == val || LONG_MIN == val)) ||


If errno == ERANGE, then there is no need to test val. It is
guaranteed to be one of the extreme values.

> ((0 != errno) && (0 == val)))


If val = 0, strtol need not set errno so it may still be zero. You
need to test endptr, not errno.

> {
> perror("strtol");
> ret = -1;
> }
> else if(endptr == str)
> {
> fprintf(stderr, "No digits were found\n");
> ret = -1;
> }
> else /* If we got here, strtol() successfully parsed a number */
> {
> printf("strtol() returned %ld\n", val);
> if ('\0' != *endptr) /* Not necessarily an error... */
> {
> printf("Further characters after number: %s\n", endptr);
> }
>
> if(INT_MAX < val || INT_MIN > val)
> {
> printf("IN: Value is greater/lower than what int can handle.
>Can not represent it in an integer\n");
> ret = -1;
> }
> else
> {
> *ip = val;
> ret = 0;
> }
> }
>
> return ret;
>}
>
>=========================== OUTPUT ===========================
>~/programs/C $ ./a.out
> i = 0, x = -2147483648
>strtol() returned -2147483648
> i = -2147483648, x = -2147483648
>INT_MAX = 2147483647
>LONG_MAX = 2147483647
>LONG_MIN = -2147483648
>~/programs/C $


--
Remove del for email
 
Reply With Quote
 
 
 
 
arnuld
Guest
Posts: n/a
 
      04-12-2012
> On Wed, 11 Apr 2012 10:49:17 -0700, Barry Schwarz wrote:

>> On 11 Apr 2012 11:22:40 GMT, arnuld <(E-Mail Removed)> wrote:


>> ...SNIP....
>> errno = 0; /* To distinguish success/failure after call */ val =
>> strtol(str, &endptr, 10);
>>
>> /* Check for various possible errors */ if ((ERANGE == errno &&
>> (LONG_MAX == val || LONG_MIN == val)) ||


> If errno == ERANGE, then there is no need to test val. It is guaranteed
> to be one of the extreme values.



In some post I read (don't remember which newsgroup) that errno can be
set by some library function even if there is no error. for that case I
tested the rest. This code actually is taken from man page of strtol.



>> ((0 != errno) && (0 == val)))

>
> If val = 0, strtol need not set errno so it may still be zero. You need
> to test endptr, not errno.


I trusted man page. Now I guess I am wrong







--
arnuld
http://LispMachine.Wordpress.com
 
Reply With Quote
 
Barry Schwarz
Guest
Posts: n/a
 
      04-12-2012
On 12 Apr 2012 05:25:35 GMT, arnuld <(E-Mail Removed)> wrote:

>> On Wed, 11 Apr 2012 10:49:17 -0700, Barry Schwarz wrote:

>
>>> On 11 Apr 2012 11:22:40 GMT, arnuld <(E-Mail Removed)> wrote:

>
>>> ...SNIP....
>>> errno = 0; /* To distinguish success/failure after call */ val =
>>> strtol(str, &endptr, 10);
>>>
>>> /* Check for various possible errors */ if ((ERANGE == errno &&
>>> (LONG_MAX == val || LONG_MIN == val)) ||

>
>> If errno == ERANGE, then there is no need to test val. It is guaranteed
>> to be one of the extreme values.

>
>
>In some post I read (don't remember which newsgroup) that errno can be
>set by some library function even if there is no error. for that case I
>tested the rest. This code actually is taken from man page of strtol.


Beware of half remembered statements or ones taken out of context.

7.5-3 states "The value of errno is zero at program startup, but is
never set to zero by any library function. The value of errno may be
set to nonzero by a library function call whether or not there is an
error, provided the use of errno is not documented in the description
of the function in this International Standard."

Since the use of errno is documented for strtol, you are guaranteed
that if errno == ERANGE, then the value has been set to one of the two
extremes as described in 7.20.1.4-8.

>
>
>
>>> ((0 != errno) && (0 == val)))

>>
>> If val = 0, strtol need not set errno so it may still be zero. You need
>> to test endptr, not errno.

>
>I trusted man page. Now I guess I am wrong


Even if a man page is correct, it only describes your particular
system. What happens if you upgrade your system or switch to a
different compiler?

If you want to know what the language requires, n1256 (C99) and n1570
(C11) are available for free downloading.

--
Remove del for email
 
Reply With Quote
 
Phil Carmody
Guest
Posts: n/a
 
      04-14-2012
Kenneth Brody <(E-Mail Removed)> writes:
> On 4/11/2012 7:22 AM, arnuld wrote:
> > I know we strtol() converts to long but I want to convert to an int. atoi
> > () does not detect errors so I don't think its advised to use it. I am
> > using strtol() anyway but putting check for INT_MAX and INT_MIN values. I
> > can not check for overflow/underflow because INT_MIN,MAX and LONG_MIN,MAX
> > have same values on my system. Can someone check of this behaves
> > correctly ?

> [...]
>
> If INT_MIN/LONG_MIN, and INT_MAX/LONG_MAX are the same on your system,
> then int and long have the same range, meaning that there is no reason
> to check the return of strtol() to see if it's outside the range of
> int.
>
> However, to be portable, your code could do something like this:
>
> long val;
>
> ... call to strtol() ...
>
> #if INT_MAX != LONG_MAX && INT_MIN != LONG_MIN


||

> if ( val < INT_MIN || val > INT_MAX )


If the #if is removed, then this might be optimised to a no-op
in the cases where the #if would be false. Depending on QoI.

> {
> ... handle error condition here ...
> }
> #endif
> return((int)val);
>
>
> --
> Kenneth Brody


--
> I'd argue that there is much evidence for the existence of a God.

Pics or it didn't happen.
-- Tom (/. uid 822)
 
Reply With Quote
 
Tim Rentsch
Guest
Posts: n/a
 
      05-07-2012
arnuld <(E-Mail Removed)> writes:

> I know we strtol() converts to long but I want to convert to an int. atoi
> () does not detect errors so I don't think its advised to use it. I am
> using strtol() anyway but putting check for INT_MAX and INT_MIN values. I
> can not check for overflow/underflow because INT_MIN,MAX and LONG_MIN,MAX
> have same values on my system. Can someone check of this behaves
> correctly ?
>


> [snip]
>
> int str_to_int(const char* str, int* ip)
> {
> char *endptr;
> long val;
> int ret;
>
> errno = 0; /* To distinguish success/failure after call */
> val = strtol(str, &endptr, 10);
>
> /* Check for various possible errors */
> if ((ERANGE == errno && (LONG_MAX == val || LONG_MIN == val)) ||
> ((0 != errno) && (0 == val)))
> {
> perror("strtol");
> ret = -1;
> }
> else if(endptr == str)
> {
> fprintf(stderr, "No digits were found\n");
> ret = -1;
> }
> else /* If we got here, strtol() successfully parsed a number */
> {
> printf("strtol() returned %ld\n", val);
> if ('\0' != *endptr) /* Not necessarily an error... */
> {
> printf("Further characters after number: %s\n", endptr);
> }
>
> if(INT_MAX < val || INT_MIN > val)
> {
> printf("IN: Value is greater/lower than what int can handle.
> Can not represent it in an integer\n");
> ret = -1;
> }
> else
> {
> *ip = val;
> ret = 0;
> }
> }
>
> return ret;
> }
>
> [snip]


The amazing thing about this code is that a whole integer
conversion routine, including the range checks, can be
written more succinctly than this. Try doing that as your
exercise, it will help your learning a lot.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
map question - need to find a string from an int but also need the int from the string? Angus C++ 3 05-03-2008 02:27 PM
Difference between int i, j; and int i; int j; arun C Programming 8 07-31-2006 05:11 AM
int a[10]; int* p=(int*)((&a)+1); But why p isn't equal to ((&a)+1)? aling C++ 8 10-20-2005 02:42 PM
int main(int argc, char *argv[] ) vs int main(int argc, char **argv ) Hal Styli C Programming 14 01-20-2004 10:00 PM
dirty stuff: f(int,int) cast to f(struct{int,int}) Schnoffos C Programming 2 06-27-2003 03:13 AM



Advertisments