digitalmars.D.learn - dynamic array of strings
- Michael P. (27/27) Dec 29 2008 import std.stdio;
- Jarrett Billingsley (3/25) Dec 29 2008 ~= performs an append. It adds the given item to the end of the array.
- Michael P. (14/40) Dec 30 2008 Under 1.036, this does not work.
- Denis Koroskin (3/46) Dec 30 2008 Now, it's not. What you do is overwrite the string again and again.
- Michael P. (3/56) Dec 30 2008 Thanks, that worked.
- Denis Koroskin (2/62) Dec 30 2008 Did you understand the difference? Can you explain the behavior (to your...
- Michael P. (2/68) Dec 30 2008 Not really... I really have no idea why it wouldn't work before.
- Denis Koroskin (23/95) Dec 30 2008 Well, let's go through the code.
- Michael P. (3/38) Dec 30 2008 So, the strings that are in the array(names) are pointers to the same bu...
- Gide Nwawudu (7/48) Jan 01 2009 currentName is used as a buffer that is overwritten on each call to
- Tim M (7/36) Dec 29 2008 Where is din.readf? If it is a c function then it won't be able to set u...
- Jarrett Billingsley (2/4) Dec 29 2008 In std.cstream, din is an instance of std.stream.Stream bound to standar...
- Tim M (3/10) Dec 29 2008 Thanks for that. As you can see I use tango.
import std.stdio; import std.cstream; void main() { char[][] names; char[] currentName; while( true ) { din.readf( "%s", ¤tName ); if( currentName == "stop" ) { break; } else { //what goes here to dynamically allocate memory for the //names array? new statement? .length? } } foreach( name; names ) { writefln( name ); } } How would I go about dynamically allocating memory for the names array in the part that I commented? I'm not really sure about the dynamic array details in D, this is just an example to help. -Michael P.
Dec 29 2008
On Mon, Dec 29, 2008 at 10:36 PM, Michael P. <baseball.mjp gmail.com> wrote:import std.stdio; import std.cstream; void main() { char[][] names; char[] currentName; while( true ) { din.readf( "%s", ¤tName ); if( currentName == "stop" ) { break; } else {names ~= currentName;} } foreach( name; names ) { writefln( name ); } }~= performs an append. It adds the given item to the end of the array.
Dec 29 2008
Jarrett Billingsley Wrote:On Mon, Dec 29, 2008 at 10:36 PM, Michael P. <baseball.mjp gmail.com> wrote:Under 1.036, this does not work. Input: michael is cool stop The output is: stopeal st stop What seems to be happening is that the letters of stop are added to the word, and if the word is longer than stop, then the rest of the letters of the word are added. So, I'm not sure if this is a bug or what... -Michael P.import std.stdio; import std.cstream; void main() { char[][] names; char[] currentName; while( true ) { din.readf( "%s", ¤tName ); if( currentName == "stop" ) { break; } else {names ~= currentName;} } foreach( name; names ) { writefln( name ); } }~= performs an append. It adds the given item to the end of the array.
Dec 30 2008
On Tue, 30 Dec 2008 18:56:08 +0300, Michael P. <baseball.mjp gmail.com> wrote:Jarrett Billingsley Wrote:Now, it's not. What you do is overwrite the string again and again. Try putting "currentName = null;" before doing din.readf().On Mon, Dec 29, 2008 at 10:36 PM, Michael P. <baseball.mjp gmail.com> wrote:Under 1.036, this does not work. Input: michael is cool stop The output is: stopeal st stop What seems to be happening is that the letters of stop are added to the word, and if the word is longer than stop, then the rest of the letters of the word are added. So, I'm not sure if this is a bug or what... -Michael P.import std.stdio; import std.cstream; void main() { char[][] names; char[] currentName; while( true ) { din.readf( "%s", ¤tName ); if( currentName == "stop" ) { break; } else {names ~= currentName;} } foreach( name; names ) { writefln( name ); } }~= performs an append. It adds the given item to the end of the array.
Dec 30 2008
Denis Koroskin Wrote:On Tue, 30 Dec 2008 18:56:08 +0300, Michael P. <baseball.mjp gmail.com> wrote:Thanks, that worked. -Michael P.Jarrett Billingsley Wrote:Now, it's not. What you do is overwrite the string again and again. Try putting "currentName = null;" before doing din.readf().On Mon, Dec 29, 2008 at 10:36 PM, Michael P. <baseball.mjp gmail.com> wrote:Under 1.036, this does not work. Input: michael is cool stop The output is: stopeal st stop What seems to be happening is that the letters of stop are added to the word, and if the word is longer than stop, then the rest of the letters of the word are added. So, I'm not sure if this is a bug or what... -Michael P.import std.stdio; import std.cstream; void main() { char[][] names; char[] currentName; while( true ) { din.readf( "%s", ¤tName ); if( currentName == "stop" ) { break; } else {names ~= currentName;} } foreach( name; names ) { writefln( name ); } }~= performs an append. It adds the given item to the end of the array.
Dec 30 2008
On Tue, 30 Dec 2008 20:23:07 +0300, Michael P. <baseball.mjp gmail.com> wrote:Denis Koroskin Wrote:Did you understand the difference? Can you explain the behavior (to yourself)?On Tue, 30 Dec 2008 18:56:08 +0300, Michael P. <baseball.mjp gmail.com> wrote:Thanks, that worked. -Michael P.Jarrett Billingsley Wrote:array.On Mon, Dec 29, 2008 at 10:36 PM, Michael P. <baseball.mjp gmail.com> wrote:import std.stdio; import std.cstream; void main() { char[][] names; char[] currentName; while( true ) { din.readf( "%s", ¤tName ); if( currentName == "stop" ) { break; } else {names ~= currentName;} } foreach( name; names ) { writefln( name ); } }~= performs an append. It adds the given item to the end of theUnder 1.036, this does not work. Input: michael is cool stop The output is: stopeal st stop What seems to be happening is that the letters of stop are added totheword, and if the word is longer than stop, then the rest of thelettersof the word are added. So, I'm not sure if this is a bug or what... -Michael P.Now, it's not. What you do is overwrite the string again and again. Try putting "currentName = null;" before doing din.readf().
Dec 30 2008
Denis Koroskin Wrote:On Tue, 30 Dec 2008 20:23:07 +0300, Michael P. <baseball.mjp gmail.com> wrote:Not really... I really have no idea why it wouldn't work before.Denis Koroskin Wrote:Did you understand the difference? Can you explain the behavior (to yourself)?On Tue, 30 Dec 2008 18:56:08 +0300, Michael P. <baseball.mjp gmail.com> wrote:Thanks, that worked. -Michael P.Jarrett Billingsley Wrote:array.On Mon, Dec 29, 2008 at 10:36 PM, Michael P. <baseball.mjp gmail.com> wrote:import std.stdio; import std.cstream; void main() { char[][] names; char[] currentName; while( true ) { din.readf( "%s", ¤tName ); if( currentName == "stop" ) { break; } else {names ~= currentName;} } foreach( name; names ) { writefln( name ); } }~= performs an append. It adds the given item to the end of theUnder 1.036, this does not work. Input: michael is cool stop The output is: stopeal st stop What seems to be happening is that the letters of stop are added totheword, and if the word is longer than stop, then the rest of thelettersof the word are added. So, I'm not sure if this is a bug or what... -Michael P.Now, it's not. What you do is overwrite the string again and again. Try putting "currentName = null;" before doing din.readf().
Dec 30 2008
On Tue, 30 Dec 2008 20:34:00 +0300, Michael P. <baseball.mjp gmail.com> wrote:Denis Koroskin Wrote:Well, let's go through the code. First of all, you should undestand that an array is nothing but a pair of pointer to first element and its length. Since char[] == string in D1, let's use string instead to make code slightly more readable. string[] names; // array of strings that will store our names string currentName; ... din.readf( "%s", ¤tName ); // what does this line do? din.readf tries to minimize allocations by accepting a buffer where the string will be stored. Buffer will be allocated on heap if provided one is too small to fit the whole string. Initially, currentName is null, i.e. currentName.ptr is null and currentName.length == 0. If you type anything, the data won't fit into buffer and therefore a new one is created by readf. When you return from readf, currentName will point to "michael" and have length == 7. When you call din.readf for second time, you pass your currentName as a buffer once again. This time it is large enough to fit "is" and therefore it is not reallocated. "is" is written on top of "michael" and becomes "ischael". currentName's length is updated to 2. Etc. Here is names' contents step by step: At Startup: string[] names = []; // empty Step 1: string[] names = [ "michael" ]; Step 2: string[] names = [ "ischael", "is" ]; Step 3: string[] names = [ "coolael", "co", "cool" ]; Step 4: string[] names = [ "stopael", "st", "stop", "stop" ]; When you reset buffer (by doing "currentName = null;"), a new one is allocated each step and each string gets its own memory. That's it.On Tue, 30 Dec 2008 20:23:07 +0300, Michael P. <baseball.mjp gmail.com> wrote:Not really... I really have no idea why it wouldn't work before.Denis Koroskin Wrote:<baseball.mjp gmail.com>On Tue, 30 Dec 2008 18:56:08 +0300, Michael P.<baseball.mjp gmail.com>wrote:Jarrett Billingsley Wrote:On Mon, Dec 29, 2008 at 10:36 PM, Michael P.Did you understand the difference? Can you explain the behavior (to yourself)?Thanks, that worked. -Michael P.array.wrote:import std.stdio; import std.cstream; void main() { char[][] names; char[] currentName; while( true ) { din.readf( "%s", ¤tName ); if( currentName == "stop" ) { break; } else {names ~= currentName;} } foreach( name; names ) { writefln( name ); } }~= performs an append. It adds the given item to the end of theUnder 1.036, this does not work. Input: michael is cool stop The output is: stopeal st stop What seems to be happening is that the letters of stop are added totheword, and if the word is longer than stop, then the rest of thelettersof the word are added. So, I'm not sure if this is a bug or what... -Michael P.Now, it's not. What you do is overwrite the string again and again. Try putting "currentName = null;" before doing din.readf().
Dec 30 2008
Well, let's go through the code. First of all, you should undestand that an array is nothing but a pair of pointer to first element and its length. Since char[] == string in D1, let's use string instead to make code slightly more readable. string[] names; // array of strings that will store our names string currentName; ... din.readf( "%s", ¤tName ); // what does this line do? din.readf tries to minimize allocations by accepting a buffer where the string will be stored. Buffer will be allocated on heap if provided one is too small to fit the whole string. Initially, currentName is null, i.e. currentName.ptr is null and currentName.length == 0. If you type anything, the data won't fit into buffer and therefore a new one is created by readf. When you return from readf, currentName will point to "michael" and have length == 7. When you call din.readf for second time, you pass your currentName as a buffer once again. This time it is large enough to fit "is" and therefore it is not reallocated. "is" is written on top of "michael" and becomes "ischael". currentName's length is updated to 2. Etc. Here is names' contents step by step: At Startup: string[] names = []; // empty Step 1: string[] names = [ "michael" ]; Step 2: string[] names = [ "ischael", "is" ]; Step 3: string[] names = [ "coolael", "co", "cool" ]; Step 4: string[] names = [ "stopael", "st", "stop", "stop" ]; When you reset buffer (by doing "currentName = null;"), a new one is allocated each step and each string gets its own memory. That's it.So, the strings that are in the array(names) are pointers to the same buffer? And if you set it to null each time, then a new buffer for each string is created instead of being overwritten? Makes sense now, thanks. -Micheal P.
Dec 30 2008
On Tue, 30 Dec 2008 10:56:08 -0500, Michael P. <baseball.mjp gmail.com> wrote:Jarrett Billingsley Wrote:currentName is used as a buffer that is overwritten on each call to din.readf. It is easier to explicitly duplicate the contents to create a copy that is stored in the array names.On Mon, Dec 29, 2008 at 10:36 PM, Michael P. <baseball.mjp gmail.com> wrote:Under 1.036, this does not work. Input: michael is cool stop The output is: stopeal st stop What seems to be happening is that the letters of stop are added to the word, and if the word is longer than stop, then the rest of the letters of the word are added. So, I'm not sure if this is a bug or what... -Michael P.import std.stdio; import std.cstream; void main() { char[][] names; char[] currentName; while( true ) { din.readf( "%s", ¤tName ); if( currentName == "stop" ) { break; } else {names ~= currentName;} } foreach( name; names ) { writefln( name ); } }~= performs an append. It adds the given item to the end of the array.names~=currentName.dup; Gidenames ~= currentName;
Jan 01 2009
On Tue, 30 Dec 2008 16:36:24 +1300, Michael P. <baseball.mjp gmail.com> wrote:import std.stdio; import std.cstream; void main() { char[][] names; char[] currentName; while( true ) { din.readf( "%s", ¤tName ); if( currentName == "stop" ) { break; } else { //what goes here to dynamically allocate memory for the //names array? new statement? .length? } } foreach( name; names ) { writefln( name ); } } How would I go about dynamically allocating memory for the names array in the part that I commented? I'm not really sure about the dynamic array details in D, this is just an example to help. -Michael P.Where is din.readf? If it is a c function then it won't be able to set up the dynamic array. You can set the length property to allocte the memory and pass the c function currentName.ptr. To append currentName to names do somehing like: names ~= currentName;
Dec 29 2008
On Mon, Dec 29, 2008 at 10:53 PM, Tim M <a b.com> wrote:Where is din.readf? If it is a c function then it won't be able to set up the dynamic array.In std.cstream, din is an instance of std.stream.Stream bound to standard in.
Dec 29 2008
On Tue, 30 Dec 2008 17:00:10 +1300, Jarrett Billingsley <jarrett.billingsley gmail.com> wrote:On Mon, Dec 29, 2008 at 10:53 PM, Tim M <a b.com> wrote:Thanks for that. As you can see I use tango.Where is din.readf? If it is a c function then it won't be able to set up the dynamic array.In std.cstream, din is an instance of std.stream.Stream bound to standard in.
Dec 29 2008