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?
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 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.
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.
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...
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
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?
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
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))
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
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
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 ?
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
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.