Page 1 of 1
Converting String to Integer
Posted: Sat Jun 16, 2007 2:36 am
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...
Posted: Sat Jun 16, 2007 2:56 am
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')
thx
Posted: Sat Jun 16, 2007 2:57 am
by Cmaranec
Ok, i will try it, thanks
works
Posted: Sat Jun 16, 2007 3:08 am
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'.
Re: works
Posted: Sat Jun 16, 2007 3:45 am
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
thx
Posted: Sat Jun 16, 2007 4:05 am
by Cmaranec
Thank you, i am doing simple calculator
Re: works
Posted: Sat Jun 16, 2007 5:13 am
by Bughunter
Cmaranec wrote:Yes, it works fine, thanks.
Great job, congrats!
...
Posted: Sat Jun 16, 2007 6:23 am
by Cmaranec
Sorry, have you got other code for convert string to integer?
Posted: Sat Jun 16, 2007 6:48 am
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.
Posted: Sat Jun 16, 2007 7:03 am
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;
}
Posted: Sat Jun 16, 2007 7:21 am
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
; --------------------------------------------------
Posted: Sat Jun 16, 2007 7:41 am
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.
thx
Posted: Sat Jun 16, 2007 8:32 am
by Cmaranec
OK, thanks to all, i will try bughunter's example
wow
Posted: Sat Jun 16, 2007 9:17 am
by Cmaranec
Wow, thanks ! All the functions works well
Re: wow
Posted: Sat Jun 16, 2007 9:21 am
by Bughunter
Cmaranec wrote:Wow, thanks ! All the functions works well
That's good to hear