 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
rolypolyman@gmail.com Guest
|
Posted: Thu Jan 20, 2005 10:48 pm Post subject: Can you dynamically resize an array? |
|
|
To anyone --
What do you do when you're dealing with arrays whose size you
can't predict? Take the following illustrative example:
var
myarray : array[1..400] of integer;
mystring : string;
myinteger, errx : integer;
begin
assignfile(infile,'c:myfile');
reset(infile);
while not eof(infile) do
begin
readln(infile,mystring);
val(copy(mystring,10,4),myinteger,errx);
inc(x);
myarray[x] := myinteger;
end;
...... do something with myarray[]
end;
How do you handle this when you can't predict how many lines of
text will be in the file? What if the user has a file containing
8000 lines of data?
It would be nice to allocate only a small amount of memory and have
the array automatically resize itself as it goes. How is this
usually done? I know I can work with pointers, too, but I'm not
clear on how to automatically resize those either.
Thanks,
RPM
|
|
| Back to top |
|
 |
Bruce Roberts Guest
|
Posted: Thu Jan 20, 2005 11:17 pm Post subject: Re: Can you dynamically resize an array? |
|
|
<rolypolyman (AT) gmail (DOT) com> wrote
| Quote: | To anyone --
What do you do when you're dealing with arrays whose size you
can't predict? Take the following illustrative example:
var
myarray : array[1..400] of integer;
|
myarray : array of integer;
| Quote: | mystring : string;
myinteger, errx : integer;
begin
assignfile(infile,'c:myfile');
reset(infile);
while not eof(infile) do
begin
readln(infile,mystring);
val(copy(mystring,10,4),myinteger,errx);
|
SetLength (myArray, Length (myArray) + 1);
| Quote: | end;
..... do something with myarray[]
end;
|
Resizing the dynamic array this way is really inefficient. It would be
better to allocate it in blocks:
SetLength (myArray, 400);
Reset (inFile);
while not eof (inFile) do
begin
. . .
inc (x);
if x > High (myArray)
then SetLength (myArray, Length (myArray) + 400);
. . .
end;
SetLength (myArray, x);
Check out "dynamic array", High, Low, and Length in the help.
|
|
| Back to top |
|
 |
rolypolyman@gmail.com Guest
|
Posted: Fri Jan 21, 2005 2:46 am Post subject: Re: Can you dynamically resize an array? |
|
|
Excellent help! Unfortunately...
Changing
myArray : array[1..100] of integer // (doesn't work with
SetLength)
to
myArray : array of integer;
causes slice(myArray,x) to stop working, due to "Slice standard
function
only allowed as open array argument". What is the problem here?
RPM
|
|
| Back to top |
|
 |
Rob Kennedy Guest
|
Posted: Fri Jan 21, 2005 5:31 am Post subject: Re: Can you dynamically resize an array? |
|
|
[email]rolypolyman (AT) gmail (DOT) com[/email] wrote:
| Quote: | Excellent help! Unfortunately...
Changing
myArray : array[1..100] of integer // (doesn't work with
SetLength)
to
myArray : array of integer;
causes slice(myArray,x) to stop working, due to "Slice standard
function
only allowed as open array argument". What is the problem here?
|
Show some context. The error message is indeed correct, so I can only
guess that you're not passing the result of that function as an
open-array parameter.
--
Rob
|
|
| Back to top |
|
 |
Bob Richardson Guest
|
Posted: Fri Jan 21, 2005 9:27 pm Post subject: Re: Can you dynamically resize an array? |
|
|
"Jamie" <jamie_5_not_valid_after_5_Please (AT) charter (DOT) net> wrote
| Quote: | rolypolyman (AT) gmail (DOT) com wrote:
To anyone --
What do you do when you're dealing with arrays whose size you
can't predict? Take the following illustrative example:
var
myarray : array[1..400] of integer;
mystring : string;
myinteger, errx : integer;
begin
assignfile(infile,'c:myfile');
reset(infile);
while not eof(infile) do
begin
readln(infile,mystring);
val(copy(mystring,10,4),myinteger,errx);
inc(x);
myarray[x] := myinteger;
end;
..... do something with myarray[]
end;
How do you handle this when you can't predict how many lines of
text will be in the file? What if the user has a file containing
8000 lines of data?
It would be nice to allocate only a small amount of memory and have
the array automatically resize itself as it goes. How is this
usually done? I know I can work with pointers, too, but I'm not
clear on how to automatically resize those either.
Thanks,
RPM
you can always use the fileSize function to obtain the number of
charactors in the file and then use a dynamic array ..
|
This is a classic use for a TStringList. It automatically resizes, and does
a LOT more. You can also use a Dynamic array.
The above program can be replaced with this, showing both approaches:
var
MyList : tstringlist;
i : integer;
MyArray : array of integer;
begin
MyList := tstringlist.create;
MyList.LoadFromFile('c:myfile');
// this brings the entire file into memory. I often have
// files with 100,000 lines...no problem
SetLength(MyArray,MyList.count); // since you now know the length of the
array
for i := 0 to MyList.count-1 do
MyArray[i] := strtointdef(copy(MyList.String[i],10,4),-999);
MyList.free; // to free up all memory for your strings
|
|
| Back to top |
|
 |
Bob Richardson Guest
|
Posted: Fri Jan 21, 2005 9:31 pm Post subject: Re: Can you dynamically resize an array? |
|
|
"Bob Richardson" <bobr at whidbey dot com> wrote
| Quote: | MyArray[i] := strtointdef(copy(MyList.String[i],10,4),-999);
|
MyArray[i] := strtointdef(copy(MyList[i],10,4),-999);
woops
|
|
| Back to top |
|
 |
Maarten Wiltink Guest
|
Posted: Fri Jan 21, 2005 10:42 pm Post subject: Re: Can you dynamically resize an array? |
|
|
"Bob Richardson" <bobr at whidbey dot com> wrote
| Quote: | "Bob Richardson" <bobr at whidbey dot com> wrote in message
news:kaCdnRoikpg77mzcRVn-3w (AT) whidbeytel (DOT) com...
MyArray[i] := strtointdef(copy(MyList.String[i],10,4),-999);
MyArray[i] := strtointdef(copy(MyList[i],10,4),-999);
woops
|
There is no "woops" about that. You'd have to have spelled it .Strings[i],
but it works. It being the default property, though, you're also allowed
to omit it.
As usual, I note that because I don't like it. When I want the object in
the i'th item in the list of strings, I write "Items.Objects[i]". Why
would I want to write "Items[i]" for the string value in that item? It's
short for "Items.Strings[i]", which actually looks congruent to the syntax
for the objects. The objects are decidedly not an afterthought meriting
some special syntax. Leaving out ".Strings" is the special syntax, and
it only serves laziness.
BTW, it's common to declare a variable such as MyList (your code) or Items
(my code) as TStrings, not TStringList. TStrings indicates what you want
from it, that it's really a TStringList is merely an implementation detail.
Groetjes,
Maarten Wiltink
|
|
| Back to top |
|
 |
Jamie Guest
|
Posted: Fri Jan 21, 2005 11:12 pm Post subject: Re: Can you dynamically resize an array? |
|
|
[email]rolypolyman (AT) gmail (DOT) com[/email] wrote:
| Quote: | To anyone --
What do you do when you're dealing with arrays whose size you
can't predict? Take the following illustrative example:
var
myarray : array[1..400] of integer;
mystring : string;
myinteger, errx : integer;
begin
assignfile(infile,'c:myfile');
reset(infile);
while not eof(infile) do
begin
readln(infile,mystring);
val(copy(mystring,10,4),myinteger,errx);
inc(x);
myarray[x] := myinteger;
end;
..... do something with myarray[]
end;
How do you handle this when you can't predict how many lines of
text will be in the file? What if the user has a file containing
8000 lines of data?
It would be nice to allocate only a small amount of memory and have
the array automatically resize itself as it goes. How is this
usually done? I know I can work with pointers, too, but I'm not
clear on how to automatically resize those either.
Thanks,
RPM
you can always use the fileSize function to obtain the number of |
charactors in the file and then use a dynamic array ..
|
|
| Back to top |
|
 |
Bob Richardson Guest
|
Posted: Sat Jan 22, 2005 5:35 pm Post subject: Re: Can you dynamically resize an array? |
|
|
"Maarten Wiltink" <maarten (AT) kittensandcats (DOT) net> wrote
| Quote: | "Bob Richardson" <bobr at whidbey dot com> wrote in message
news:NrydnbfRbd4Q6WzcRVn-vQ (AT) whidbeytel (DOT) com...
"Bob Richardson" <bobr at whidbey dot com> wrote in message
news:kaCdnRoikpg77mzcRVn-3w (AT) whidbeytel (DOT) com...
MyArray[i] := strtointdef(copy(MyList.String[i],10,4),-999);
MyArray[i] := strtointdef(copy(MyList[i],10,4),-999);
woops
There is no "woops" about that. You'd have to have spelled it .Strings[i],
but it works. It being the default property, though, you're also allowed
to omit it.
As usual, I note that because I don't like it. When I want the object in
the i'th item in the list of strings, I write "Items.Objects[i]". Why
would I want to write "Items[i]" for the string value in that item? It's
short for "Items.Strings[i]", which actually looks congruent to the syntax
for the objects. The objects are decidedly not an afterthought meriting
some special syntax. Leaving out ".Strings" is the special syntax, and
it only serves laziness.
BTW, it's common to declare a variable such as MyList (your code) or Items
(my code) as TStrings, not TStringList. TStrings indicates what you want
from it, that it's really a TStringList is merely an implementation
detail.
|
I agree that MyList[i] is the special syntax, while MyList.Strings[i] is the
more general and probably better approach for someone new to Delphi. In the
same vein, I think that declaring MyList as a TStrings, rather than a
TStringList, is a special syntax situation. The move from Pascal to Delphi
(which the op seems to be going through) can be a bit confusing. It was for
me. I think the "general form" is
var
MyObj : TWhateverObj;
begin
MyObj := tWhateverObj.create;
...
MyObj.free;
end;
We're only quibbling over what's in Delphi 101, and what's in Delphi 102.
I think
var
MyList : TStrings;
begin
MyList := TStringList.create;
is a second semester topic.
|
|
| Back to top |
|
 |
Maarten Wiltink Guest
|
Posted: Sat Jan 22, 2005 9:20 pm Post subject: Re: Can you dynamically resize an array? |
|
|
"Bob Richardson" <bobr at whidbey dot com> wrote
[...]
| Quote: | We're only quibbling over what's in Delphi 101, and
what's in Delphi 102. I think
var
MyList : TStrings;
|
<as opposed to TStringList>
| Quote: | begin
MyList := TStringList.create;
is a second semester topic.
|
That would be true if TStrings/TStringList weren't _the_ number one
standard Delphi trick. It would suffer putting off full polymorphism
to the second week, but declaring all TStringLists TStrings by default
should be a reflex before you even know why you're _allowed_ to do it,
much less why it's a good idea.
Groetjes,
Maarten Wiltink
|
|
| Back to top |
|
 |
Steve Parus Guest
|
Posted: Mon Jan 24, 2005 6:38 pm Post subject: Re: Can you dynamically resize an array? |
|
|
Not automatic, but what can be done is to initially declare a dynamic
array of some size ArraySize. Then with each line read in, check if
the number of elements is close to ArraySize. If so, then increase
the value of ArraySize by some increment and resize the dynamic array
with SetLength(MyArray, ArraySize)
| Quote: | rolypolyman (AT) gmail (DOT) com wrote:
It would be nice to allocate only a small amount of memory and have
the array automatically resize itself as it goes.
|
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|