News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Convert numeric to string

Started by masterori, March 04, 2016, 02:59:27 PM

Previous topic - Next topic

masterori

I have an array of int and I need to convert each number into strings. Anyone know the best way to do this

Lets say int_array contains: 123,34,56, etc...

I was thinking: I want to loop through that and make each value their own array -> so 123 will become 1,2,3. Then convert each value into its ascii then print it out to console.

Is this the correct way? Since strings are stored as byte of char right?


rrr314159

Yes, that's exactly the right idea. As usual there are more details that could be mentioned.

The most important is: there are functions available that do the task for you, such as str$ and itoa (integer to ascii). I'll leave it to others, with more time on their hands, to tell you all about them. Ideally, you should do it yourself first (learn by doing!), subsequently use such "canned" functions to save time and effort, also produce more readable code.

I think you already see, conceptually, how to successively divide by 10 to change 123 => 1,2,3; if you have trouble with the details, ask.

It would be cleaner (not necessary, tho) to go from the number 123 directly to the string "49, 50, 51, 0", instead of creating (as you say) an intermediate array "1,2,3".

From your last thread I see you already know how to convert [0 - 9] to the ascii [48 - 57], and that strings must be terminated with a 0.

BTW strings aren't necessarily bytes of char; they can be words, using unicode. Doesn't matter for your current task.
I am NaN ;)

masterori

I think I'm not sure what you mean by 123 into "49,50,51,0". You mean convert them into ascii then combine into a string?
Also, I'm not too clear on how to get '3' from 123. As the remaining of dividing by 10 only gives you 1,2 with 10 going into 3 zero times.

rrr314159

Hmmm ... it gets a bit complicated. Ignore my suggestion to go directly to the ascii 49, 50, etc; instead do it in 2 steps, as you first said: generate the 1, 2 first, then make it ascii.

Conceptually,

in a loop:

divide 123 by 10, getting 12 in eax, and 3 (the remainder) in edx. Save the "3" in a byte array (which is the same thing as a string).
Then divide the 12 by 10, getting 1 and 2; save the 2.
Divide the 1 by 10, getting 0 and 1; save the 1.
At each step you've been testing the result for 0; now it is 0, so fall through the loop.

Now, loop thru the resulting array, adding 48 to each of 1, 2, and 3. Put 0 at the end of it, one way or another.

When you save the 3, 2, 1, either do it in reverse order, or else reverse the order as you go thru them adding 48.

The string is now ready to print out!

For division, consult MASM opcodes help to see how div (or, idiv; either is good here) works.

Or, look at the code in masm32/m32lib/itoa.asm for a much easier approach, using a canned function (wsprintf).

See how far you can get with that advice ... even if you don't succeed you'll learn a lot more by trying. Plus, if you put in that effort, I'll be willing to take you the next step. Else wait awhile, dedndave will (sooner or later) give you the exact code necessary for the job, plus lots more advice about many other fine points.
I am NaN ;)

masterori

Forget about my comment about not understanding how to get the 3 from dividing 123 by 10. It's pretty late over here and I was thinking of 123/10 = 1 R 23 But it's not fully divided >.< Since it is 12 R 3. Okay I'll give it a shot tomorrow and let you guys know (I haven't tried going through an array in reverse yet, so will have to look that up). Is there a way to get the offset of the last value or is that what '$' is for?

Assembly is definitely harder compared to higher level languages...

dedndave

the string "comes out" in reverse - start by setting a 0 (null terminator) at the end of the buffer

decrement the pointer
you divide 123 by 10 - you get 12, with a remainder of 3
convert the remainder to ASCII by adding 30h
store that byte

the quotient (12) is non-zero, so continue the loop

decrement the pointer
you divide 12 by 10 - you get 1, with a remainder of 2
convert the remainder to ASCII by adding 30h
store that byte

the quotient (1) is non-zero, so continue the loop

decrement the pointer
you divide 1 by 10 - you get 0, with a remainder of 1
convert the remainder to ASCII by adding 30h
store that byte

the quotient (0) is zero, so exit the loop
return the pointer in EAX
some routines "left-justify" the string in the buffer
but, it's easier to return a pointer and leave it right-justified

converting a string to a number is essentially the reverse operation
however, each string byte must be validated
if it's not a number, then your code has to have some way to handle it
if the string is too long or the value is too large, your code has to have some way to handle that

masterori

How do I get the last offset of an array?
I've tried this but doesn't seem to work

mov ebx,counter        ; counter counted the number of digits stored in reverse when dividing by 10 then minus 1
mov edi,ptr_array[ebx*type ptr_array]

It's probably the pointer right?

TouEnMasm


To adress a structure,you need to know... his adress

Lea ebx,MyStructure
mov eax,[ebx].MyStructure.AnyData

MyStructure STRUCT
depot DWORD ?
AnyData DWORD ?
MyStructure ENDS
Fa is a musical note to play with CL

jj2007

Quote from: masterori on March 05, 2016, 05:20:04 PMIt's probably the pointer right?

Probably, yes. We could be even certain if you posted your complete code, instead of letting us guess what you might have done so far.

Quote from: ToutEnMasm on March 05, 2016, 07:11:34 PMTo adress a structure,you need to know... his adress
Yves, nobody is talking about structures here. He's a noob, don't confuse him more than necessary.
Besides, "structure" is neutral, so it's "its address", not "his address" (members are a male attribute, though 8))

dedndave

that is not a good example of structure usage

but, you don't need a structure, anyways
you just need a buffer and it's size

    .DATA?

MyBuffer db 12 dup(?)

    .CODE

    mov     edx,offset MyBuffer+sizeof MyBuffer-1  ;EDX = address of last byte in buffer

Vortex

Hello masterori,

Here is a quick example for you :

.386
.model flat,stdcall
option casemap:none

include     \masm32\include\windows.inc
include     \masm32\include\kernel32.inc
include     \masm32\include\masm32.inc

includelib  \masm32\lib\kernel32.lib
includelib  \masm32\lib\masm32.lib

NumbToStr   PROTO :DWORD,:DWORD

.data

.data?

buff        db 11 dup(?)        ; the maximum unsigned number
                                ; stored by a DWORD = 4294967295 ( 10 chars )
                                ; size of the buffer = 10 + 1
                                ; the last character is the NULL terminator
.code

start:

    invoke  NumbToStr,123,ADDR buff

    invoke  StdOut,eax

    invoke  ExitProcess,0

NumbToStr PROC uses ebx x:DWORD,buffer:DWORD

    mov     ecx,buffer
    mov     eax,x
    mov     ebx,10
    add     ecx,ebx             ; ecx = buffer + max size of string
@@:
    xor     edx,edx
    div     ebx
    add     edx,48              ; convert the digit to ASCII
    mov     BYTE PTR [ecx],dl   ; store the character in the buffer
    dec     ecx                 ; decrement ecx pointing the buffer
    test    eax,eax             ; check if the quotient is 0
    jnz     @b

    inc     ecx
    mov     eax,ecx             ; eax points the string in the buffer
    ret

NumbToStr ENDP

END start

TouEnMasm

You are not too much clear in what you want to do.
Quote
I was thinking: I want to loop through that and make each value their own array -> so 123 will become 1,2,3. Then convert each value into its ascii then print it out to console
If I translate:
You have a dword = 123 in decimal
You want to extract the number of hundred (100)  = 1,place it in a dword ,NbHundred = 1
You want to extract the number of  (10)                = 2                             Nbten = 2
you want to extract the number of unit                  = 3                             NbUnit = 3
Then convert those values in ascii char ?
The convert is easy , asciiNbHundred  = NbHundred +30h
Is it that you want to do ?
look like a sholar exercise,not ?
Fa is a musical note to play with CL

masterori

I've already converted the decimal over to ascii char. But because I did 123/10 to get 1,2,3 they are stored as 3,2,1 in my array. So I need to reverse them to 1,2,3 and that's why I was asking how to get the offset address of the last element so I can exchange the values.

edit: got the reversing to work

Vortex

Hi masterori,

No need to reverse the string. You can check the source code posted above. First, you get a pointer to the end of the buffer and decrement it after copying a digit to the buffer.