Page 1 of 1

whats wrong with this string to int conversion code

Posted: Sat Feb 18, 2006 9:50 pm
by earlz
I am trying to figure out what is wrong with this code and cannot see one problem

Code: Select all

unsigned int str2num(char *str){
   unsigned int num=0,digit=0;
   while (*str!=0){
     num=num+((*str-48)*upwr(10,digit)); //upwr is unsigned power and works
     digit++;str++;
   }
   return num;
}

Re:whats wrong with this string to int conversion code

Posted: Sun Feb 19, 2006 1:34 am
by Candy
you multiply the first number with 10^0, the second with 10^1 and the third with 10^2. You convert 123 to 321.

Try:

Code: Select all

int atoi (char *str) {
  int num;
  while (*str) {
    num = num * 10 + *(str++) - 48;
  }
  return num;
}
Next time, before wondering why code doesn't work, try out the algorithm on paper first.

Re:whats wrong with this string to int conversion code

Posted: Sun Feb 19, 2006 2:20 am
by earlz
i did try working it out on paper but for some reason i was thinking i typed it different for some reason so it made it backwards

Re:whats wrong with this string to int conversion code

Posted: Mon Feb 20, 2006 1:16 am
by Solar
<nitpicking mode>

The code also relies on '0' at 48 and '9' at 57. That is true for ASCII, but it is not true for EBCDIC and a couple others. You also did ignore the issue of leading spaces and signs (check the documentation on atoi()!).

Taking from my PDCLib:

Code: Select all

#include <ctype.h>

char _PDCLIB_digits[] = "0123456789";

int atoi( const char * s )
{
    int rc = 0;
    char sign = '+';
    const char * x;
    /* TODO: In other than "C" locale, additional patterns may be defined */
    while ( isspace( *s ) ) ++s;
    if ( *s == '+' ) ++s;
    else if ( *s == '-' ) sign = *(s++);
    while ( ( x = memchr( _PDCLIB_digits, *(s++), 10 ) ) != NULL )
    {
        rc = rc * 10 + ( x - _PDCLIB_digits );
    }
    return ( sign == '+' ) ? rc : -rc;
}
That should be pretty portable. As you can see from the comment, other locales may define more valid digits, but you don't have to support them.

Re:whats wrong with this string to int conversion code

Posted: Sat Mar 04, 2006 5:27 pm
by earlz
wow thanks

i thought i looked at that function before and it was a return somehting_i_dont_remeber();

Re:whats wrong with this string to int conversion code

Posted: Mon Mar 06, 2006 2:27 am
by Solar
Jordan3 wrote: i thought i looked at that function before and it was a return somehting_i_dont_remeber();
Correct:

Code: Select all

int atoi( const char * s )
{
    return (int) _PDCLIB_atomax( s );
}
That's a bit of trickery there. [tt]atoi()[/tt], [tt]atol()[/tt] and [tt]atoll()[/tt] basically use the very same code. Now, you could simply make [tt]atoi()[/tt] and [tt]atol()[/tt] call [tt]atoll()[/tt] and cast the result (as the standard does not require you to handle overflow correctly, as opposed to the [tt]strtol()[/tt] function family).

The problem is that [tt]atoll()[/tt] is only available since C99 - if PDCLib is compiled for C89, it is not yet available. That's why I made a function [tt]_PDCLIB_atomax()[/tt] which does the conversion to the largest type supported by the language version.

Long story short, I whittled down the complexity so I could provide you with a "simple" [tt]atoi()[/tt] here. ;-)