Thread overview | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
February 25, 2012 Write struct to file | ||||
---|---|---|---|---|
| ||||
Hello! import std.stdio; struct nagger { string name; int age; double weight; string msg; } void main() { auto lal = new nagger(); lal.name = "AHAHAHAHHA"; lal.age = 23; lal.weight = 108.5; lal.msg = "fgfdgfdgfdgfdgfdgfdg"; writeln(cast(ubyte[])(lal)); } Gives error: Error: e2ir: cannot cast lal of type nagger* to type ubyte[] I have bad knowledge about this and don't understand why I cant do this :( What I really want is an array of naggers and save them binary to a file :) This was like my step 1, and it failed miserably... Thanks for help. |
February 25, 2012 Re: Write struct to file | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chopin | On 02/25/2012 07:03 PM, Chopin wrote: > Hello! > > import std.stdio; > > struct nagger > { > string name; > int age; > double weight; > string msg; > } > > void main() > { > auto lal = new nagger(); > lal.name = "AHAHAHAHHA"; > lal.age = 23; > lal.weight = 108.5; > lal.msg = "fgfdgfdgfdgfdgfdgfdg"; > writeln(cast(ubyte[])(lal)); > } > > Gives error: Error: e2ir: cannot cast lal of type nagger* to type ubyte[] > I have bad knowledge about this and don't understand why I cant do this :( > What I really want is an array of naggers and save them binary to a file :) > This was like my step 1, and it failed miserably... > > Thanks for help. > Structs are not castable to arrays directly. You can achieve what you want like this (untested, but should work). (cast(void*)&lal)[0..nagger.sizeof]; |
February 25, 2012 Re: Write struct to file | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On 02/25/2012 07:15 PM, Timon Gehr wrote: > On 02/25/2012 07:03 PM, Chopin wrote: >> Hello! >> >> import std.stdio; >> >> struct nagger >> { >> string name; >> int age; >> double weight; >> string msg; >> } >> >> void main() >> { >> auto lal = new nagger(); >> lal.name = "AHAHAHAHHA"; >> lal.age = 23; >> lal.weight = 108.5; >> lal.msg = "fgfdgfdgfdgfdgfdgfdg"; >> writeln(cast(ubyte[])(lal)); >> } >> >> Gives error: Error: e2ir: cannot cast lal of type nagger* to type ubyte[] >> I have bad knowledge about this and don't understand why I cant do >> this :( >> What I really want is an array of naggers and save them binary to a >> file :) >> This was like my step 1, and it failed miserably... >> >> Thanks for help. >> > > Structs are not castable to arrays directly. You can achieve what you > want like this (untested, but should work). > > (cast(void*)&lal)[0..nagger.sizeof]; > You also have to change the first line of main to: auto lol = nagger(); This will allocate the struct on the stack. If you want to keep auto lal = new nagger(); for some reason, then do the cast like this: (cast(void*)lal)[0..nagger.sizeof] |
February 25, 2012 Re: Write struct to file | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chopin | Well first I'd recommend not allocating the struct on the heap. Then you can do: import std.stdio; struct nagger { string name; int age; double weight; string msg; } void main() { nagger lal; lal.name = "name"; lal.age = 23; lal.weight = 108.5; lal.msg = "msg"; auto file = File("test.bin", "w"); auto writeBytes = fwrite(&lal, byte.sizeof, lal.sizeof, file.getFP()); file.close(); nagger dup; file = File("test.bin", "r"); auto readBytes = fread(&dup, byte.sizeof, dup.sizeof, file.getFP()); assert(lal == dup); } This doesn't work for heap-allocated structs. |
February 25, 2012 Re: Write struct to file | ||||
---|---|---|---|---|
| ||||
On 2/25/12, Andrej Mitrovic <andrej.mitrovich@gmail.com> wrote:
> This doesn't work for heap-allocated structs.
>
Sorry my bad. .sizeof should always be set on Types and not variable names, because a struct pointer will have sizeof == size_t, whereas a simple struct variable will have sizeof equal to the struct size. So it can work just fine with heap-allocated structs:
void main()
{
auto lal = new nagger();
lal.name = "name";
lal.age = 23;
lal.weight = 108.5;
lal.msg = "msg";
auto file = File("test.bin", "w");
auto writeBytes = fwrite(cast(void*)lal, byte.sizeof,
nagger.sizeof, file.getFP());
file.close();
nagger dup;
file = File("test.bin", "r");
auto readBytes = fread(&dup, byte.sizeof, nagger.sizeof, file.getFP());
assert(dup == *lal);
}
|
February 25, 2012 Re: Write struct to file | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | On 02/25/2012 10:33 AM, Andrej Mitrovic wrote: > Well first I'd recommend not allocating the struct on the heap. Then you can do: > > import std.stdio; > > struct nagger > { > string name; > int age; > double weight; > string msg; > } > > void main() > { > nagger lal; > lal.name = "name"; > lal.age = 23; > lal.weight = 108.5; > lal.msg = "msg"; > > auto file = File("test.bin", "w"); > auto writeBytes = fwrite(&lal, byte.sizeof, lal.sizeof, file.getFP()); But there is no way for fwrite to follow name.ptr to also write the characters that are in the string, right? > file.close(); > > nagger dup; > file = File("test.bin", "r"); > auto readBytes = fread(&dup, byte.sizeof, dup.sizeof, file.getFP()); > > assert(lal == dup); That passes because lal.name.ptr and dup.name.ptr have the same value. Maybe that wasn't the intention but the data is not really in the file. > } > > This doesn't work for heap-allocated structs. Ali |
February 25, 2012 Re: Write struct to file | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On 2/25/12, Ali Çehreli <acehreli@yahoo.com> wrote:
> That passes because lal.name.ptr and dup.name.ptr have the same value. Maybe that wasn't the intention but the data is not really in the file.
I'm not sure where you're getting that from:
import std.stdio;
struct nagger
{
string name;
int age;
double weight;
string msg;
}
void main(string[] args)
{
if (args[1] == "write")
{
nagger lal;
lal.name = "name";
lal.age = 23;
lal.weight = 108.5;
lal.msg = "msg";
auto file = File("test.bin", "w");
auto writeBytes = fwrite(&lal, byte.sizeof, lal.sizeof, file.getFP());
}
else
if (args[1] == "read")
{
nagger dup;
auto file = File("test.bin", "r");
auto readBytes = fread(&dup, byte.sizeof, dup.sizeof, file.getFP());
writeln(dup);
}
}
$ rdmd test.d write
$ rdmd test.d read
nagger("name", 23, 108.5, "msg")
|
February 25, 2012 Re: Write struct to file | ||||
---|---|---|---|---|
| ||||
To be honest the C fread and fwrite aren't even necessary since you can do a rawRead and rawWrite instead. |
February 25, 2012 Re: Write struct to file | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On 2/25/12, Ali Çehreli <acehreli@yahoo.com> wrote:
> But there is no way for fwrite to follow name.ptr to also write the characters that are in the string, right?
Oh my I just got a big fat zero on the finals. You're absolutely right, what gets copied is the length and the pointer. The only reason my last sample worked is because the memory for the strings was allocated on the stack, which had the same address between runs.
|
February 25, 2012 Re: Write struct to file | ||||
---|---|---|---|---|
| ||||
On 2/26/12, Andrej Mitrovic <andrej.mitrovich@gmail.com> wrote:
> allocated on the stack
Sorry, I meant the data segment not the stack. That's -1 score for me.
|
Copyright © 1999-2021 by the D Language Foundation