Jump to page: 1 2
Thread overview
Write struct to file
Feb 25, 2012
Chopin
Feb 25, 2012
Timon Gehr
Feb 25, 2012
Timon Gehr
Feb 25, 2012
Andrej Mitrovic
Feb 25, 2012
Ali Çehreli
Feb 25, 2012
Andrej Mitrovic
Feb 25, 2012
Andrej Mitrovic
Feb 25, 2012
Andrej Mitrovic
Feb 25, 2012
Ali Çehreli
Feb 26, 2012
Chopin
Feb 27, 2012
Ali Çehreli
Feb 27, 2012
Andrej Mitrovic
Feb 28, 2012
Chopin
Feb 25, 2012
Andrej Mitrovic
Feb 25, 2012
Andrej Mitrovic
Feb 25, 2012
Andrej Mitrovic
February 25, 2012
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
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
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
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
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
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
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
To be honest the C fread and fwrite aren't even necessary since you can do a rawRead and rawWrite instead.
February 25, 2012
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
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