Buffered Files & Associative Arrays

Gide Nwawudu gide at btinternet.com
Wed Jan 23 09:36:32 PST 2008


On Tue, 22 Jan 2008 03:35:01 -0500, Michael <mcoupland at gmail.com>
wrote:

>Greetings all!
>
>When I compile and run the below program with a sample input test.txt file, I get some very strange behavior. It behaves like a problem with strange strings coming from a BufferedFile that for some reason the associative array can't handle.
>
>With test.txt containing three one-character lines:
>	a
>	b
>	c
>
>...I get the output:
>	a 1 
>	b 2 b 2 
>	c 3 c 3 c 3 
>
>...rather than the expected:
>	a 1 
>	a 1 b 2 
>	a 1 b 2 c 3 
>
>With test.txt containing longer strings:
>	first
>	second
>	third
>
>...the program crashes entirely with the following output:
>	first 1
>	Error: ArrayBoundsError TestArray(15)
>
>
>However, if I replace the two relevant lines with the following:
>	string[] file = ["first","second","third"]; // or ["a","b","c"]
>	foreach( int n, string line; file )
>
>...then the program runs as expected. But what's the difference?? Adding newlines to the string constants above doesn't do any harm, which was what I had first suspected as the culprit.
>
>I don't think I'm missing anything obvious; can someone please confirm I'm not crazy?
>
>Thanks!
>	Michael
>
>--------------------------------------------------------------
>
>import std.stdio;
>import std.stream;
>
>int main( char[][] args )
>{
>	int[string] Ar;
>	
>	Stream file = new BufferedFile("test.txt");
>	
>	foreach( ulong n, string line; file )
>	{
>		Ar[line] = n;
>		
>		foreach( string k; Ar.keys )
>			writef("%s %d ", k, Ar[k] );
>
>		writefln("");
>	}
>
>	return 0;
>}

Without D2's const/invariant enhancements it is very easy introduce
this bug. FWIW your code does not compile on D2. The following code
produces the correct output.

import std.stdio;
import std.stream;

int main( char[][] args )
{
    int[string] Ar;
    
    Stream file = new BufferedFile("test.txt");
    
    foreach( ulong n, char[] line; file ) // mutable line variable
    {
        Ar[line.idup] = n;  // idup needed
        
        foreach( string k; Ar.keys )
            writef("%s %d ", k, Ar[k] );

        writefln("");
    }

    return 0;
}



Gide



More information about the Digitalmars-d mailing list