digitalmars.D.learn - r/w binary
- Joel Christensen (27/27) Jun 28 2011 I want to save and load levels for my game. The std.stream module
- Ali =?iso-8859-1?q?=C7ehreli?= (7/39) Jun 28 2011 That is copy-paste mistake, right? You don't want create() before
- Joel Christensen (5/44) Jun 29 2011 Thanks for your reply Ali.
- Joel Christensen (26/26) Jun 29 2011 With the char[], I can't use spaces in it the way I've got it here,
- Ali =?iso-8859-1?q?=C7ehreli?= (22/34) Jun 29 2011 There has been a thread very recently about reading strings. Look for th...
- Joel Christensen (9/43) Jun 29 2011 I'm thinking more about handling binary files. With the C version I
- Ali =?iso-8859-1?q?=C7ehreli?= (27/31) Jun 30 2011 I would still use a portable text format myself.
- Joel Christensen (5/36) Jun 30 2011 Yes, portability, I hadn't thought of that.
- Ali =?iso-8859-1?q?=C7ehreli?= (5/7) Jun 30 2011 [0..1] follows the regular slicing syntax there: those are element
- Joel Christensen (3/10) Jul 01 2011 Ok, I get you. A whole int*, not one byte of the int* data.
I want to save and load levels for my game. The std.stream module doesn't have much examples. Here is my code: void saveLevel( string fileName ) { auto bfile = new std.stream.File; int ver = 1; string verStr = "version:"; with( bfile ) { scope( exit ) close; create( fileName ); write( verStr ); write( ver ); // version } int ver2; char[] verStr2; auto bfile2 = new std.stream.File; with( bfile2 ) { scope( exit ) close; create( fileName ); read( verStr2 ); read( ver2 ); // version } writeln( verStr, ver ); } And this is the result: std.stream.ReadException std\stream.d(46): Stream is not readable - Joel
Jun 28 2011
I've settled on std.stdio as opposed to std.stream and std.cstream. On Wed, 29 Jun 2011 10:07:13 +1200, Joel Christensen wrote:I want to save and load levels for my game. The std.stream module doesn't have much examples. Here is my code: void saveLevel( string fileName ) { auto bfile = new std.stream.File; int ver = 1; string verStr = "version:"; with( bfile ) { scope( exit ) close; create( fileName ); write( verStr ); write( ver ); // version } int ver2; char[] verStr2; auto bfile2 = new std.stream.File; with( bfile2 ) { scope( exit ) close; create( fileName );That is copy-paste mistake, right? You don't want create() before reading. You must have meant open: open( fileName ); It works with that change.read( verStr2 ); read( ver2 ); // version } writeln( verStr, ver ); } And this is the result: std.stream.ReadException std\stream.d(46): Stream is not readable - JoelAli
Jun 28 2011
Thanks for your reply Ali. Your right about changing create to open when reading. And, yes, I was thinking of trying std.stdio myself. - Joel On 29-Jun-11 6:48 PM, Ali Çehreli wrote:I've settled on std.stdio as opposed to std.stream and std.cstream. On Wed, 29 Jun 2011 10:07:13 +1200, Joel Christensen wrote:I want to save and load levels for my game. The std.stream module doesn't have much examples. Here is my code: void saveLevel( string fileName ) { auto bfile = new std.stream.File; int ver = 1; string verStr = "version:"; with( bfile ) { scope( exit ) close; create( fileName ); write( verStr ); write( ver ); // version } int ver2; char[] verStr2; auto bfile2 = new std.stream.File; with( bfile2 ) { scope( exit ) close; create( fileName );That is copy-paste mistake, right? You don't want create() before reading. You must have meant open: open( fileName ); It works with that change.read( verStr2 ); read( ver2 ); // version } writeln( verStr, ver ); } And this is the result: std.stream.ReadException std\stream.d(46): Stream is not readable - JoelAli
Jun 29 2011
With the char[], I can't use spaces in it the way I've got it here, (like if I tried using a phrase): void saveLevel( string fileName ) { int ver = 1; auto house = "two".dup; double rnum = 3.0; { auto fout = File( fileName, "wb"); // open for binary writing scope( exit ) fout.close; fout.writef( "%d %s %f", ver, house, rnum ); } ver = 593; house = "asdfghf".dup; rnum = 57.23; { auto fin = File( fileName, "rb"); // open for binary reading scope( exit ) fin.close; fin.readf( "%d %s %f", &ver, &house, &rnum ); } writeln( "\nint: ", ver, " string: '", house, "' rnum: ", rnum ); } - Joel
Jun 29 2011
On Wed, 29 Jun 2011 19:55:38 +1200, Joel Christensen wrote:With the char[], I can't use spaces in it the way I've got it here, (like if I tried using a phrase):There has been a thread very recently about reading strings. Look for the thread "readf with strings" (dated 22-Jun-2011 in my reader). Or, if it works here: http://www.digitalmars.com/webnews/newsgroups.php? art_group=digitalmars.D.learn&article_id=27762 Reading the entire line: string s = chomp(readln()); Kai Meyer suggested parsing the string directly: string[] buffer; int a; float b; string c; buffer = chomp(readln()).split(" "); a = to!(int)(buffer[0]); b = to!(float)(buffer[1]); c = buffer[2..$].join(" "); writef("Read in: '%d' '%f' '%s'\n", a, b, c);void saveLevel( string fileName ) { int ver = 1; auto house = "two".dup; double rnum = 3.0; { auto fout = File( fileName, "wb"); // open for binarywriting scope(exit ) fout.close;You are not supposed to need to close the File object yourself. Being a struct, its destructor should be called automatically. Ali
Jun 29 2011
I'm thinking more about handling binary files. With the C version I would write a int for how many letters in the string, then put in the the string along side ([0005][house]). That way I can have any character at all (though I just thinking of char's). Actually, I've just looked the output file and it's a text file. So in that case I would use read line to have spaces in strings, though what if I wanted to have new line character(s) in the one string. I still want to work with binary files. On 30-Jun-11 2:23 AM, Ali Çehreli wrote:On Wed, 29 Jun 2011 19:55:38 +1200, Joel Christensen wrote:With the char[], I can't use spaces in it the way I've got it here, (like if I tried using a phrase):There has been a thread very recently about reading strings. Look for the thread "readf with strings" (dated 22-Jun-2011 in my reader). Or, if it works here: http://www.digitalmars.com/webnews/newsgroups.php? art_group=digitalmars.D.learn&article_id=27762 Reading the entire line: string s = chomp(readln()); Kai Meyer suggested parsing the string directly: string[] buffer; int a; float b; string c; buffer = chomp(readln()).split(" "); a = to!(int)(buffer[0]); b = to!(float)(buffer[1]); c = buffer[2..$].join(" "); writef("Read in: '%d' '%f' '%s'\n", a, b, c);void saveLevel( string fileName ) { int ver = 1; auto house = "two".dup; double rnum = 3.0; { auto fout = File( fileName, "wb"); // open for binarywriting scope(exit ) fout.close;You are not supposed to need to close the File object yourself. Being a struct, its destructor should be called automatically. Ali
Jun 29 2011
On Thu, 30 Jun 2011 15:52:59 +1200, Joel Christensen wrote:I'm thinking more about handling binary files. With the C version I would write a int for how many letters in the string, then put in the the string along side ([0005][house]). That way I can have any character at all (though I just thinking of char's).I would still use a portable text format myself. For binary, you should consider rawWrite() and rawRead(). Here is just a start: import std.stdio; void main() { int i = 42; auto file = File("deleteme.bin", "w"); file.rawWrite((&i)[0..1]); } (Aside: The 'b' for binary mode does nothing in POSIX systems; so it's not necessary.) The parameter to rawWrite() above is a nice feature of D: slicing a raw pointer produces a safe slice: http://digitalmars.com/d/2.0/arrays.html <quote> Slicing is not only handy for referring to parts of other arrays, but for converting pointers into bounds-checked arrays: int* p; int[] b = p[0..8]; </quote> For strings (actually arrays), you would need .length and .ptr properties. I've never used it but you might want to consider the serialization library Orange as well: http://www.dsource.org/projects/orange Ali
Jun 30 2011
Yes, portability, I hadn't thought of that. Shouldn't file.rawWrite((&i)[0..1]); have [0..4]? Or am I missing some thing? - Joel On 30-Jun-11 7:53 PM, Ali Çehreli wrote:On Thu, 30 Jun 2011 15:52:59 +1200, Joel Christensen wrote:I'm thinking more about handling binary files. With the C version I would write a int for how many letters in the string, then put in the the string along side ([0005][house]). That way I can have any character at all (though I just thinking of char's).I would still use a portable text format myself. For binary, you should consider rawWrite() and rawRead(). Here is just a start: import std.stdio; void main() { int i = 42; auto file = File("deleteme.bin", "w"); file.rawWrite((&i)[0..1]); } (Aside: The 'b' for binary mode does nothing in POSIX systems; so it's not necessary.) The parameter to rawWrite() above is a nice feature of D: slicing a raw pointer produces a safe slice: http://digitalmars.com/d/2.0/arrays.html <quote> Slicing is not only handy for referring to parts of other arrays, but for converting pointers into bounds-checked arrays: int* p; int[] b = p[0..8]; </quote> For strings (actually arrays), you would need .length and .ptr properties. I've never used it but you might want to consider the serialization library Orange as well: http://www.dsource.org/projects/orange Ali
Jun 30 2011
On Fri, 01 Jul 2011 05:28:56 +1200, Joel Christensen wrote:Shouldn't file.rawWrite((&i)[0..1]); have [0..4]? Or am I missing some thing?[0..1] follows the regular slicing syntax there: those are element indexes. Since &i is an int*, [0..1] slices the first int. It would be different if it were ubyte* or void*. Ali
Jun 30 2011
Ok, I get you. A whole int*, not one byte of the int* data. - Joel On 01-Jul-11 6:07 AM, Ali Çehreli wrote:On Fri, 01 Jul 2011 05:28:56 +1200, Joel Christensen wrote:Shouldn't file.rawWrite((&i)[0..1]); have [0..4]? Or am I missing some thing?[0..1] follows the regular slicing syntax there: those are element indexes. Since&i is an int*, [0..1] slices the first int. It would be different if it were ubyte* or void*. Ali
Jul 01 2011