Thread overview | ||||||
---|---|---|---|---|---|---|
|
April 02, 2008 Help with Associative array problems. | ||||
---|---|---|---|---|
| ||||
The program below does not print what it should, either using a File or the TArrayStream. It prints this: user@vm-fruitbat:~$ dmd t.d user@vm-fruitbat:~$ ./t Error: 4invalid UTF-8 sequence Material user@vm-fruitbat:~$ I can "fix" it by saying: m[words[1].dup] = 1 But why does the original 'go wrong' import std.stdio; import std.string; import std.stream; void main() { //Stream file = new File("test.txt"); TArrayStream!(char[]) file = new TArrayStream!(char[])("newmtl one\nnewmtl two"); int [char[]] m; foreach(ulong line_no, ref string line; file) { string words[] = line.split(); m[words[1]] = 1; } foreach (char[] k, ref int v; m) { writefln("Material %s", k); } } |
April 02, 2008 Re: Help with Associative array problems. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Spacen Jasset | Spacen Jasset wrote: > The program below does not print what it should, either using a File or the TArrayStream. > > It prints this: > > user@vm-fruitbat:~$ dmd t.d > user@vm-fruitbat:~$ ./t > Error: 4invalid UTF-8 sequence > Material user@vm-fruitbat:~$ > [snip] > foreach(ulong line_no, ref string line; file) { > string words[] = line.split(); > m[words[1]] = 1; } > foreach (char[] k, ref int v; m) { > writefln("Material %s", k); > } > } File.opApply (which is called by foreach), as implemented in superclass Stream, re-uses a (stack-allocated) buffer for each iteration. This is more efficient, but means the string put into the loop variable is only valid for that iteration; if you want to keep it beyond that you need to allocate a copy. This is mentioned in the documentation for InputStream[1]: "The string passed in line may be reused between calls to the delegate." [1] <http://www.digitalmars.com/d/1.0/phobos/std_stream.html>, search for "opApply". |
April 02, 2008 Re: Help with Associative array problems. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Frits van Bommel | Frits van Bommel wrote:
> Spacen Jasset wrote:
>> The program below does not print what it should, either using a File or the TArrayStream.
>>
>> It prints this:
>>
>> user@vm-fruitbat:~$ dmd t.d
>> user@vm-fruitbat:~$ ./t
>> Error: 4invalid UTF-8 sequence
>> Material user@vm-fruitbat:~$
>>
> [snip]
>> foreach(ulong line_no, ref string line; file) {
>> string words[] = line.split();
>> m[words[1]] = 1; }
>> foreach (char[] k, ref int v; m) {
>> writefln("Material %s", k);
>> }
>> }
>
> File.opApply (which is called by foreach), as implemented in superclass Stream, re-uses a (stack-allocated) buffer for each iteration. This is more efficient, but means the string put into the loop variable is only valid for that iteration; if you want to keep it beyond that you need to allocate a copy.
> This is mentioned in the documentation for InputStream[1]: "The string passed in line may be reused between calls to the delegate."
>
>
> [1] <http://www.digitalmars.com/d/1.0/phobos/std_stream.html>, search for "opApply".
I see ok. This is all very subtle though. Is my solution adding a .dup the best way or can I do something else?
|
April 03, 2008 Re: Help with Associative array problems. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Spacen Jasset | Spacen Jasset wrote:
> I see ok. This is all very subtle though. Is my solution adding a .dup the best way or can I do something else?
If you need the string after the iteration of the loop in which it was bound, .dup is the best way to do so. (The original gets overwritten, so make a copy if you need it later -- not rocket science ;) )
Unless you're using D2-series compiler, in which case .idup may be better (especially for use as AA keys).
|
Copyright © 1999-2021 by the D Language Foundation