digitalmars.D.learn - Help with Associative array problems.
- Spacen Jasset (27/27) Apr 02 2008 The program below does not print what it should, either using a File or
- Frits van Bommel (11/29) Apr 02 2008 File.opApply (which is called by foreach), as implemented in superclass
- Spacen Jasset (3/34) Apr 02 2008 I see ok. This is all very subtle though. Is my solution adding a .dup
- Frits van Bommel (6/8) Apr 03 2008 If you need the string after the iteration of the loop in which it was
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); } }
Apr 02 2008
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".
Apr 02 2008
Frits van Bommel wrote: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?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".
Apr 02 2008
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).
Apr 03 2008