Converting String to Integer

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
Cmaranec
Member
Member
Posts: 45
Joined: Sat Oct 21, 2006 1:07 pm
Location: Czech Republic

Converting String to Integer

Post by Cmaranec »

Hello,
how can i convert integer to (for example) char dd[128] ? I tried to create function like IntToStr (from Pascal), but it didn't work...
Last edited by Cmaranec on Sat Jun 16, 2007 3:11 am, edited 1 time in total.
Sorry for my bad English...
User avatar
Bughunter
Member
Member
Posts: 94
Joined: Mon Dec 18, 2006 5:49 am
Location: Netherlands
Contact:

Post by Bughunter »

1. Divide the value by the base of the numbering system (for decimal, the base is 10)
2. Convert the remainder value of the division to ASCII (for decimal, this is usually done by adding 0x30)
3. Check if the quotient of the division is 0, if it is _not_ then go back to step 1.
4. When the loop ends, reverse the string buffer (for example '54321' becomes '12345')
Cmaranec
Member
Member
Posts: 45
Joined: Sat Oct 21, 2006 1:07 pm
Location: Czech Republic

thx

Post by Cmaranec »

Ok, i will try it, thanks
Sorry for my bad English...
Cmaranec
Member
Member
Posts: 45
Joined: Sat Oct 21, 2006 1:07 pm
Location: Czech Republic

works

Post by Cmaranec »

Yes, it works fine, thanks.

Question 2: How can i convert string to integer? (with error code) i have char firstc[64]; and char secndc[64]; and int first; and int secnd; and i want to "copy" all from 'firstc' to 'first' and from 'secndc' to 'secnd'.
Sorry for my bad English...
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: works

Post by Brendan »

Cmaranec wrote:Yes, it works fine, thanks.

Question 2: How can i convert string to integer? (with error code) i have char firstc[64]; and char secndc[64]; and int first; and int secnd; and i want to "copy" all from 'firstc' to 'first' and from 'secndc' to 'secnd'.
Something like this perhaps?

Code: Select all

char *convertStringToInt(int *number, char *string) {
    if(strncasecmp(string, "0x", 2) == 0) {
        // Hexadecimal
        return convertStringToIntWithBase(number, &string[2], 16);
    }
    if(*string == '0') {
        // Octal???
        return convertStringToIntWithBase(number, &string[1], 8);
    }
    // Decimal
    return convertStringToIntWithBase(number, string, 10);
}


char *convertStringToIntWithBase(int *number, char *string, int base) {
    int digit;

    *number = 0;

    for(;;) {
        if( (*string >= '0') && (*string <= '9') )  {
            digit = *string - '0';
        } else if( (*string >= 'A') && (*string <= 'Z') )  {
            digit = *string - 'A' + 10;
        } else if( (*string >= 'a') && (*string <= 'z') )  {
            digit = *string - 'a' + 10;
        } else {
            break;
        }
        if(digit >= base) {
            break;
        }
        if(*number >= INT_MAX / base) {
            return NULL; // Will overflow...
        }
        *number = *number * base;
        if(*number >= INT_MAX - digit) {
            return NULL; // Will overflow...
        }
        *number = *number + digit;
        string++;
    }
    return string;
}
Of course you can do more. For e.g. supporting binary, handling leading '-' and '+' characters, supporting arbitrary number bases (e.g. "0r6r54321" could be a number in base 6), handling exponents (e.g. "-1E2" could be -100 in decimal), etc. You could also combine all of that, so that "-0r4r32100E-0r16r1" is a base 4 number with a negative base 16 exponent (in this case, -57 in decimal). ;)


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Cmaranec
Member
Member
Posts: 45
Joined: Sat Oct 21, 2006 1:07 pm
Location: Czech Republic

thx

Post by Cmaranec »

Thank you, i am doing simple calculator :D
Sorry for my bad English...
User avatar
Bughunter
Member
Member
Posts: 94
Joined: Mon Dec 18, 2006 5:49 am
Location: Netherlands
Contact:

Re: works

Post by Bughunter »

Cmaranec wrote:Yes, it works fine, thanks.
Great job, congrats! 8)
Cmaranec
Member
Member
Posts: 45
Joined: Sat Oct 21, 2006 1:07 pm
Location: Czech Republic

...

Post by Cmaranec »

Sorry, have you got other code for convert string to integer?
Sorry for my bad English...
User avatar
Bughunter
Member
Member
Posts: 94
Joined: Mon Dec 18, 2006 5:49 am
Location: Netherlands
Contact:

Post by Bughunter »

Basically, you make a loop and pick a character each loop, convert the character back to a raw value, then multiply that by 10 each loop iteration. Oh yes, start at the end of the string and decrease your counter every iteration.

I'll see if I have an example laying around.
User avatar
Bughunter
Member
Member
Posts: 94
Joined: Mon Dec 18, 2006 5:49 am
Location: Netherlands
Contact:

Post by Bughunter »

Here is an example:

Code: Select all

int atodw(const char *str) {
    int value = 0;

    for(int counter = strlen(str)-1, multiplier = 1; !(counter < 0); --counter, multiplier *= 10) {
        value += (str[counter] - 0x30) * multiplier;
    }
   
    return value;
}
User avatar
XCHG
Member
Member
Posts: 416
Joined: Sat Nov 25, 2006 3:55 am
Location: Wisconsin
Contact:

Post by XCHG »

Here is a function that I have coded for my kernel that converts an unsigned string to a 32-bit Unsigned DWORD value. This one is optimized and it wouldn't use the MUL instruction at all for multiplication:

Code: Select all

; --------------------------------------------------
  __StrToDWORD:
    ; DWORD __StrToDWORD (const char* InStr)
    PUSH    EBX
    PUSH    EDX
    PUSH    EBP
    MOV     EBP , ESP
    MOV     EBX , DWORD PTR [EBP + 0x10]
    XOR     EAX , EAX
    .Loop:
      MOV     EDX , DWORD PTR [EBX]
      AND     EDX , 0x000000FF
      JE      .EP
      AND     EDX , 0x0000000F
      ADD     EAX , EAX
      LEA     EAX , [EAX + 0x04*EAX]
      ADD     EAX , EDX
      INC     EBX
      JMP     .Loop
    .EP:
      POP     EBP
      POP     EDX
      POP     EBX
    RET     0x04
; --------------------------------------------------
On the field with sword and shield amidst the din of dying of men's wails. War is waged and the battle will rage until only the righteous prevails.
User avatar
Bughunter
Member
Member
Posts: 94
Joined: Mon Dec 18, 2006 5:49 am
Location: Netherlands
Contact:

Post by Bughunter »

I have written a similar function ASM some time ago. Cmaranec wanted a C function so why post the ASM one? Since Cmaranec also asked how to convert a string back to an integer, I don't think he understands much of ASM since he's just exploring calculators :)

Imho, you shouldn't overthrow someone with 'complicated' stuff that they will probably not (yet) understand.
Cmaranec
Member
Member
Posts: 45
Joined: Sat Oct 21, 2006 1:07 pm
Location: Czech Republic

thx

Post by Cmaranec »

OK, thanks to all, i will try bughunter's example
Sorry for my bad English...
Cmaranec
Member
Member
Posts: 45
Joined: Sat Oct 21, 2006 1:07 pm
Location: Czech Republic

wow

Post by Cmaranec »

Wow, thanks ! All the functions works well 8)
Sorry for my bad English...
User avatar
Bughunter
Member
Member
Posts: 94
Joined: Mon Dec 18, 2006 5:49 am
Location: Netherlands
Contact:

Re: wow

Post by Bughunter »

Cmaranec wrote:Wow, thanks ! All the functions works well 8)
That's good to hear :D
Post Reply