View mode: basic / threaded / horizontal-split · Log in · Help
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
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
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
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
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
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
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.
« First   ‹ Prev
1 2
Top | Discussion index | About this forum | D home