News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

How do you read a string into an array?

Started by bcddd214, April 27, 2011, 02:53:41 AM

Previous topic - Next topic

bcddd214

I have been working with numbers and now tinkering around with strings and arrays.

If the string is an unknown size and requires user input, what is the best approach for this?

Tight_Coder_Ex

I most often use stack for input and when the actuall size is known, then either use memory that's already been allocated or grab whatever I need from heap.  This is assuming your input is 4096 characters or less.

dedndave

for console input, you can usually just limit the number of input characters to some number larger than needed
in most cases, that is less than 256 bytes
the input functions let you set the limit by telling it how large the buffer is
many win32 functions that have a variable-length buffer work that way
so - for that size, it doesn't hurt to declare the buffer in .DATA?
the stack is a nice way to go, also, if it is temporary data
if you want to keep the info permanently, DB is easier   :P

mineiro

you can put in the first byte preceding the string, the number of bytes of that string.
if you have a string "hello", you store it in your array like "5""hello". Five here means 5 characters follow.
But you need limit the number of input characters, like Sr Dedndave sayd. In this example, is limited to 255 and not 256, continue reading.
How you know where is the next entry in your table(array) that are free to insert a new string?
You search for the next entry that have a 0(zero) preceding the string. This is why you can get 255 maximum chars and not 256.

Another way is:
You can insert a 0(zero, or another character that the user will neve input) in the end of string, so you know where it ends.
But how you know where is the next avaliable entry to your array?
You search for two zeros (00).

You can mix both ways above too, like inserting the count of chars in the start of each index, and put a zero in the end of each string.

bcddd214

Quote from: Tight_Coder_Ex on April 27, 2011, 03:23:19 AM
I most often use stack for input and when the actuall size is known, then either use memory that's already been allocated or grab whatever I need from heap.  This is assuming your input is 4096 characters or less.

I know this word heap. It refers to the reserved memory for a hash?

for this purpose, I would like to assume that a persons name is less than 30 characters.

Insight as to what to do if it was a million character would be nice but I am only looking to build a little program that assumes the normal length of a name.

Whats the best method my friend?

hutch--

You can do an array in the data section something like this.


.data?
  mbr1 db 256 dup (?)
  mbr2 db 256 dup (?)
  mbr3 db 256 dup (?)
  mbr4 db 256 dup (?)
  mbr5 db 256 dup (?)
  mbr6 db 256 dup (?)

.data
  parr dd mbr1, mbr2, mbr3, mbr4, mbr5, mbr6


parr is the pointer to the array of 6 members.

If you are writing an array of large unknown size members, you get the length first IE: from a file, allocate memory for each item and place that in a pointer array. You have to remember to de-allocate the memory for each array member if you take this approach.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

bcddd214

Quote from: mineiro on April 27, 2011, 04:09:45 AM
you can put in the first byte preceding the string, the number of bytes of that string.
if you have a string "hello", you store it in your array like "5""hello". Five here means 5 characters follow.
But you need limit the number of input characters, like Sr Dedndave sayd. In this example, is limited to 255 and not 256, continue reading.
How you know where is the next entry in your table(array) that are free to insert a new string?
You search for the next entry that have a 0(zero) preceding the string. This is why you can get 255 maximum chars and not 256.

Another way is:
You can insert a 0(zero, or another character that the user will neve input) in the end of string, so you know where it ends.
But how you know where is the next available entry to your array?
You search for two zeros (00).

You can mix both ways above too, like inserting the count of chars in the start of each index, and put a zero in the end of each string.

can't you just set the variable to 'offset' and let it grow in an array?

bcddd214

I just want to read (via user input) a name into a register.
Push into an array
pop it out
then push it in backwards (working with LIFO).


hutch--

That won't work, you ned allocated memory and place a pointer to that memory in a register.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

dedndave

one way to do what you want would be to create an array of string like Hutch said
  mbr1 db 256 dup (?)
  mbr2 db 256 dup (?)
  mbr3 db 256 dup (?)
  mbr4 db 256 dup (?)
  mbr5 db 256 dup (?)
  mbr6 db 256 dup (?)

then, instead of trying to push the name entered onto the stack, push the address of the name onto the stack
then, the addresses will pop off in reverse order, as desired

in this case, you do not need an array of pointers
  parr dd mbr1, mbr2, mbr3, mbr4, mbr5, mbr6
because each string buffer is 256 bytes
it is easy to calculate the address of a particular one by multiplying the index by 256 and adding the address of the first one
(256 being a power of 2 makes the multiplication very simple)

the strings above may be numbered 1 through 6, but those are just names   :P
you may refer to them as 0 through 5
then use that as the index

so, if you want the 4th string (index = 3)
offset mbr1 + 256*3 is the address

bcddd214

Quote from: dedndave on April 27, 2011, 03:38:32 AM
for console input, you can usually just limit the number of input characters to some number larger than needed
in most cases, that is less than 256 bytes
the input functions let you set the limit by telling it how large the buffer is
many win32 functions that have a variable-length buffer work that way
so - for that size, it doesn't hurt to declare the buffer in .DATA?
the stack is a nice way to go, also, if it is temporary data
if you want to keep the info permanently, DB is easier   :P

Everything is temporary 'per se'. I am just trying to make sure I have a REAL good understanding of the registers and pop. None of what I am doing has any real world application. Just getting past the learning curve is all.

dedndave

well - using the stack is a good idea when the information is only needed briefly
it does not "waste" unused memory

i use it, myself, quite often   :bg
sometimes, i want to make room on the stack for a small buffer
        pushad
the PUSHAD instruction pushes all 8 registers on the stack with a single byte
i may not care what is there - i just want to make some room - lol
in many cases, win32 functions want a structure that begins with the size of that structure
        mov     edi,sizeof SOMESTRUCTURE
        pushad

because the EDI register is the last of the 8 to be pushed, my structure size is already initialized   :P
ESP points to the base of the structure

bcddd214

Quote from: mineiro on April 27, 2011, 04:09:45 AM
you can put in the first byte preceding the string, the number of bytes of that string.
if you have a string "hello", you store it in your array like "5""hello". Five here means 5 characters follow.
But you need limit the number of input characters, like Sr Dedndave sayd. In this example, is limited to 255 and not 256, continue reading.
How you know where is the next entry in your table(array) that are free to insert a new string?
You search for the next entry that have a 0(zero) preceding the string. This is why you can get 255 maximum chars and not 256.

Another way is:
You can insert a 0(zero, or another character that the user will neve input) in the end of string, so you know where it ends.
But how you know where is the next avaliable entry to your array?
You search for two zeros (00).

You can mix both ways above too, like inserting the count of chars in the start of each index, and put a zero in the end of each string.

Wait, wouldn't 'offset' handle this?

bcddd214

Quote from: hutch-- on April 27, 2011, 04:26:14 AM
That won't work, you ned allocated memory and place a pointer to that memory in a register.

I know, your locked in on 256. Your seeing what I am supposed to.
I am the baby looking for what is possible.

Lets assume UNDER 256 and work in a really safe realm.

:)

bcddd214

Quote from: dedndave on April 27, 2011, 04:35:34 AM
one way to do what you want would be to create an array of string like Hutch said
  mbr1 db 256 dup (?)
  mbr2 db 256 dup (?)
  mbr3 db 256 dup (?)
  mbr4 db 256 dup (?)
  mbr5 db 256 dup (?)
  mbr6 db 256 dup (?)

then, instead of trying to push the name entered onto the stack, push the address of the name onto the stack
then, the addresses will pop off in reverse order, as desired

in this case, you do not need an array of pointers
  parr dd mbr1, mbr2, mbr3, mbr4, mbr5, mbr6

I like this "push the address of the name onto the stack
then, the addresses will pop off in reverse order, as desired"
Your pushing me into pointers which was going to be my next question.....   :)
because each string buffer is 256 bytes
it is easy to calculate the address of a particular one by multiplying the index by 256 and adding the address of the first one
(256 being a power of 2 makes the multiplication very simple)

the strings above may be numbered 1 through 6, but those are just names   :P
you may refer to them as 0 through 5
then use that as the index

so, if you want the 4th string (index = 3)
offset mbr1 + 256*3 is the address

You appear to be creating a number of arrays?