Re: Segmentation fault on closing file in destructor
Hi Jérôme, On 09/26/2010 10:59 PM, Jérôme M. Berger wrote: The way I see it, there are two possible situations: 1. You really need precise control as to when the file is closed. In that case, your class contains an explicit cleanup function that you call before dropping the last reference and you can close the file at that time; 2. You only need to be sure that the file gets closed at some point but it doesn't really signify when. In that case, you let the GC collect your class and you don't close the file. Eventually the GC will collect the std.stream.File instance which will result in calling its destructor which will close the file without your needing to do anything about it. That are probably the two choices I have, yes. I already have such a cleanup function and will probably go for that. Thanks, Tom
Re: Segmentation fault on closing file in destructor
Hi, On 09/26/2010 10:05 PM, Simen kjaeraas wrote: Can you use scope(exit) or the std.stdio.File? Well, I have no idea. You mentioning scope(exit) was actually the first time I heard of it. Unfortunately I have not found any resource about it. Do you have a link to point me in the right direction? http://digitalmars.com/d/2.0/statement.html#ScopeGuardStatement thanks, strange I did not find that page by searching. Good to know about that concept, but I guess it is not fitting as a solution here. My scope is the from creation to destrution of the class, so this will no be working. But anyway, thanks. Tom
Re: Segmentation fault on closing file in destructor
Hi, On 09/27/2010 02:09 PM, Steven Schveighoffer wrote: On Sun, 26 Sep 2010 20:20:18 -0400, Michel Fortin In fact, it's generally a good idea to not wait for the GC to collect your objects before closing files, because waiting for the GC could take an indeterminate amount of time and leave files open for a long time (the GC only runs when needed). Yes, this is true no matter what File construct you use. I'll keep that in mind and will go for a cleanup method that I have to call explicitely. Especially files should probably only be opened if in use or if one wants to prevent others from using it. Cheers, Tom
Segmentation fault on closing file in destructor
Hi, a file reading class of mine can be constructed with a filename as parameter. It instantiates a new std.stream.File (without the passed file name and closes it when opened within the destructor. The last part is where things are getting unclear for me. On the file.isOpen() call in the destructor a segmentation fault occurs. What is the problem with that? Thanks in advance, Tom An example class to demonstrate the problem: import std.stdio; import std.string; import std.stream; class FileReader(T) { string filename; // the name of the object file std.stream.File file; // the object file public: this(string filename) { // make an immutable copy of the filename this.filename = filename.idup; file = new std.stream.File(); } // destructor ~this() { if(file.isOpen()) // crashes here writefln(open); } // open file, return true if successful bool open() { try { file = new std.stream.File(filename, FileMode.In); } catch(OpenException e) { writefln([Error] Could not open file: ~ filename); return false; } return true; } }
Re: Segmentation fault on closing file in destructor
Hi, On 09/26/2010 07:13 PM, bearophile wrote: Tom Kazimiers: Do you have any suggestion how I should make sure that the file gets closed on destruction? Can you use scope(exit) or the std.stdio.File? Well, I have no idea. You mentioning scope(exit) was actually the first time I heard of it. Unfortunately I have not found any resource about it. Do you have a link to point me in the right direction? If I would use std.stdio.File, what would be different? Thanks, Tom
Re: FIle I/O
Hi Graham, On 09/16/2010 04:28 PM, Graham Nicholls wrote: I'm writing a program to take a file and convert it into a binary format which matches the format produced by a system which we use. If I get it right, this will allow me to replay the file into the system. However I can't find how to do I/O in D. I've got the D Programming Language and Tango books, but not much there, and as a C/C++ programmer, Tango doesn't seem that appealing :-). Is there a tutorial anywhere? in case you did not find some example code yet: http://www.dprogramming.com/FileTutorial.html Regards, Tom
Re: FIle I/O
Graham, On 09/16/2010 05:02 PM, Graham Nicholls wrote: Is this D 1.0 ? I get errors regarding printf - I understood that writeln was the 2.0 way. Yes, I think it's D 1.0. For a D 2.0 version I replaced those printf's with writeln's, too. Bye, Tom
Convert strings with different format to float
Hi, I try to read data in from a file. This data consist mainly of numbers and I have a hard time converting it to number type variables. Two data lines could look like this v 0 0 0 v 1.5 1.2 0 Now I want to parse those lines and call a method, the line in passed (as char[]) to it: int index = indexOf(line, v ); if(index != -1) { vc++; float x = 0.0, y = 0.0, z = 0.0; char[][] vertexCoords = split( line[index+2 .. $] ); if (vertexCoords.length 0) x = to!int(vertexCoords[0]); if (vertexCoords.length 1) y = to!int(vertexCoords[1]); if (vertexCoords.length 2) z = to!int(vertexCoords[2]); process_vertex(vc,x,y,z); return; } First I split the remaining characters (after v ) into parts (here is probably dynamic copying included?). Then I want to convert each part to a float value. The problem I have is that I obviously need to use to!int for numbers with out decimal point and to!float for numbers with. But since those can be mixed I would ask for every part if there is a decimal point, e.g: if (vertexCoords.length 0) { if (indexOf(vertexCoords[0], .) != -1) x = to!float(vertexCoords[0]); else x = to!int(vertexCoords[0]); } Is there a more convient way to achieve that? I am coming from C++ and IIRC one could do there sth. like this: int index = line.find(v ); if(index != std::string::npos) { line.erase(0,index+1); vc++; float x,y,z = 0; std::istringstream ins; ins.str(line); ins x y z; process_vertex(vc,x,y,z); return; } That looks much cleaner to me (besides the operators). So I am looking for sth. similar in D :-). Maybe a to!float that can cope with numbers without decimal point. Cheers, Tom
Re: Convert strings with different format to float
Hi, On 09/08/2010 10:02 AM, Stanislav Blinov wrote: I would have thought that to!float() could handle a number without a decimal point. If it can't I would suggest creating a bug report for it. Now, since such a fix would not help you immediately in either case, I would suggest creating a wrapper function which took a string and then used to!int() for numbers without decimal points and to!float() for number with them, and then returned a float. That way, you wouldn't have to keep worrying about it. Also, you could try parse(). It might be more forgiving. - Jonathan M Davis No it wouldn't :) It's indeed a bug, and it happens if string contains e.g. single 0 (other digits are parsed normally). It seems that parse for floating points tries to determine if the number is in hex format, thus eating first 0, but it does not reuse this 0 later while it tries to pop next characters (and that results in assertion in std.array). thanks for your answers. Indeed, it is a bug. As Don states no bug report is needed, because it is fixed for a couple of weeks (in svn). In the meantime (of waiting for upcoming release) I will, as Jonathan suggested, create a wrapper function. Cheers, Tom
Re: Convert strings with different format to float
On 09/08/2010 06:58 PM, Stanislav Blinov wrote: 08.09.2010 20:46, Tom Kazimiers wrote: Great! I am looking forward to that release :-). Any idea when it will be available? For the mean time I will, as proposed, make a separate function that checks if there is a dot in it or not. Then I take to!float and to!int, respectively. Cheers, Tom That won't really help against this bug: to!float(0.) will also trigger assertion. You probably should just check if string contains single 0. Ah, thanks, I must have missed that! Regards, Tom
Re: Fast temporary dynamic arrays? (And slicing of them)
Hi, thanks for your tests. On 09/06/2010 04:59 AM, bearophile wrote: My first test shows that it may work. But I have to grow the array backwards, and push back the array start, because that's how my stack grows (using alloca to allocate geometrically bigger chunks). So unless you want to reverse the items once the array is built, you have to change the algorithm that uses the array a little. Unfortunately I need the elements to stay in the order I have added them. But good to know that it would work with backward growing of the array - do have you an example of that? Cheers, Tom
Fast temporary dynamic arrays? (And slicing of them)
Hi all, so I have started to look at D and dug through the documentation, but could not get a good answer on the following: How can I have a (temporary) dynamic array on stack and make references to it (no copying)? I successively put integers in an array (but don't know how much there will be in advance) with an appender!(int[]) and get the date out with appender.data(). Later on I pass the result to a method as an in int[] parameter. Is that already a reference or will it be copied? Are there better methods to accomplish this? The method receiving such an array will not modifiy contents of the array, but only read from it. Thanks in advance, Tom -- P.s. To put a bit of context around that, here some notes on what I am working (some questions here as well, but above is the primary one): My first try-out project in D is an Object file reader (often used in computer graphics). Part of that is a parsing method which parses a single line that contains a definition of a face (a polygon). It could for instance look like this: f 1//10 2//10 3//10 That means it is a triangle face of points 1, 2 and 3 (three groups, first number is point index). Furthermore no texture coordinate index (no number between two slashes) and each with normal vector index 10. But I don't want to go into detail of that. Say I want to parse that line with D and in the end call a method to process that face with references to lists of the different point indices: void process_face(int index, int vcount, in int[] vertices, in int[] texcoords = null, in int[] normals = null) { ... } (I guess in means sth. like const reference) The arrays should not be copied, but be references. The line parsing method now has the following lines (line is a char[]): //search face int index = indexOf(line, f ); if(index != -1) { line = line[index+2 .. $]; // slice away the f part fc++; // increment face count int slash; while(true) { slash = indexOf(line, /); // leading spaces + slashes? if(slash != -1) // remove space line = line[0 .. slash] ~ line[slash+1 .. $]; else break; } while(true) { slash = indexOf(line, / ); // trailing spaces + slashes? if(slash != -1) // remove space line = line[0 .. slash+1] ~ line[slash+2 .. $]; else break; } // dynamic vertex, texture and normal arrays auto vIndices = appender!(int[])(); auto tIndices = appender!(int[])(); auto nIndices = appender!(int[])(); // some indices int vi,ti,ni; // split line on white spaces char[][] vertexCoords = split( line ); // go through each part - are those splittings ok? foreach(char[] coord; vertexCoords) { vi = parse!(int)(coord); //get int from string vIndices.put( vi ); // save it in vertex array if (coord[0] == '/') { // follows a slash? coord = coord[1 ..$]; // get rid of it if (coord[0] == '/') { // follows another slash? coord = coord[1 ..$]; // get rid of it ni = parse!(int)( coord ); // git following int nIndices.put( ni ); // save it in normal array } else { ti = parse!(int)( coord ); tIndices.put( ti ); if (coord[0] == '/') { coord = coord[1 ..$]; int ni = parse!(int)( coord ); nIndices.put( ni ); } } } } // array references for passing to processing method int[] varray = null, tarray = null, narray = null; // if we have data, save it to appropriate varible if( !(vIndices.data().empty()) ) varray = vIndices.data(); if( !(tIndices.data().empty()) ) tarray = tIndices.data(); if( !(nIndices.data().empty()) ) narray = nIndices.data(); // process it process_face(fc, vIndices.data().length, varray, tarray, narray); return; } I hope this rather lengthy explanation is no problem here (if looked on it at all, since it was not my primary question :-) ). If you are in the mood, please comment on how make parts on it better. It is pretty much my first D code. Well, thanks. Cheers Tom