On Tue, 30 Dec 2008 20:34:00 +0300, Michael P. <[email protected]> wrote:
Denis Koroskin Wrote:
On Tue, 30 Dec 2008 20:23:07 +0300, Michael P. <[email protected]>
wrote:
> Denis Koroskin Wrote:
>
>> On Tue, 30 Dec 2008 18:56:08 +0300, Michael P.
<[email protected]>
>> wrote:
>>
>> > Jarrett Billingsley Wrote:
>> >
>> >> On Mon, Dec 29, 2008 at 10:36 PM, Michael P.
<[email protected]>
>> >> 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.
>> >
>> > 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.
>>
>> Now, it's not. What you do is overwrite the string again and again.
>> Try putting "currentName = null;" before doing din.readf().
>
> Thanks, that worked.
> -Michael P.
Did you understand the difference? Can you explain the behavior (to
yourself)?
Not really... I really have no idea why it wouldn't work before.
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.