Thread overview
Reading file as binary
May 29, 2013
baws
May 29, 2013
baws
May 29, 2013
Adam D. Ruppe
May 29, 2013
Ali Çehreli
May 29, 2013
bearophile
May 29, 2013
bearophile
May 29, 2013
Ali Çehreli
May 30, 2013
baws
May 30, 2013
Ali Çehreli
May 29, 2013
Im trying to learn D, lovely language for a C++ lover. I have a file Im trying to parse, but I need to read the contents as binary data. I also need help understanding how read() works. I'd like to read the first four bytes which identify the file header, I need it to show as a sequence of bytes, how can i output the first 4 bytes to show like 0xFFCF?

With my code, im getting the integer values, If i use cast(byte[]) on read and writefln("Reading header info: 0x%x", bytesRead[0]);

Ill only get the first byte 0xCF.


import std.stdio;
import std.file;
import std.array;

struct xsdhead{
    int head1;
    int head2;
    int numTables;
};

immutable int headerInfo1 = 0xFFCF;
immutable int headerInfo2 = 0x0002;

int main(string [] args){
    writeln("start");
    if(args[1] == null){
        writeln("pass a file");
        return 0;
    }
    auto file = args[1];
    writeln("Working on ", file);

    auto bytesRead =  cast(byte[]) read(file, 4);
    writefln("Reading header info: %s", bytesRead);
    writefln("Address of caret is: 0x%X", &bytesRead);

    return 0;
}
May 29, 2013
On Wednesday, 29 May 2013 at 22:03:24 UTC, baws wrote:
> Im trying to learn D, lovely language for a C++ lover. I have a file Im trying to parse, but I need to read the contents as binary data. I also need help understanding how read() works. I'd like to read the first four bytes which identify the file header, I need it to show as a sequence of bytes, how can i output the first 4 bytes to show like 0xFFCF?
>
> With my code, im getting the integer values, If i use cast(byte[]) on read and writefln("Reading header info: 0x%x", bytesRead[0]);
>
> Ill only get the first byte 0xCF.
>
>
> import std.stdio;
> import std.file;
> import std.array;
>
> struct xsdhead{
>     int head1;
>     int head2;
>     int numTables;
> };
>
> immutable int headerInfo1 = 0xFFCF;
> immutable int headerInfo2 = 0x0002;
>
> int main(string [] args){
>     writeln("start");
>     if(args[1] == null){
>         writeln("pass a file");
>         return 0;
>     }
>     auto file = args[1];
>     writeln("Working on ", file);
>
>     auto bytesRead =  cast(byte[]) read(file, 4);
>     writefln("Reading header info: %s", bytesRead);
>     writefln("Address of caret is: 0x%X", &bytesRead);
>
>     return 0;
> }

Oh clap guys, sorry for wasting time, I just noticed the std.stdio.File library! Ill come back to this later!
May 29, 2013
On Wednesday, 29 May 2013 at 22:03:24 UTC, baws wrote:
> With my code, im getting the integer values, If i use cast(byte[]) on read and writefln("Reading header info: 0x%x", bytesRead[0]);

You're reading the file correctly, just not printing it all out in hex.

>     writefln("Reading header info: %s", bytesRead);

this line should be printing the right data, just in decimal notation instead of hex. If you do the %x with one byte at a time you'll probably get the output you want:

        byte[] a = [10, 16, 32, 123];
        writef("0x");
        foreach(b; a)
            writef("%x", b);
        writef("\n");
May 29, 2013
On 05/29/2013 03:23 PM, Adam D. Ruppe wrote:

>          byte[] a = [10, 16, 32, 123];
>          writef("0x");
>          foreach(b; a)
>              writef("%x", b);
>          writef("\n");

There is also the nested array formatting. Pretty cool but dyslecix! :)

    writefln("0x%(%x%)", a);

Ali

May 29, 2013
Ali Çehreli:

>     writefln("0x%(%x%)", a);

But usually I prefer to show all the zero nibbles:

void main() {
    import std.stdio;
    ubyte[] a = [10, 16, 32, 123];
    writefln("0x%(%02x%)", a); // Output: 0xa10207b
    static assert(is(typeof(a[0]) == ubyte), "Only ubyte[]");
    writefln("0x%(%x%)", a);   // Output: 0x0a10207b
}

Bye,
bearophile
May 29, 2013
> void main() {
>     import std.stdio;
>     ubyte[] a = [10, 16, 32, 123];
>     writefln("0x%(%02x%)", a); // Output: 0xa10207b
>     static assert(is(typeof(a[0]) == ubyte), "Only ubyte[]");
>     writefln("0x%(%x%)", a);   // Output: 0x0a10207b
> }

I have pasted the outputs inverted, sorry.

Bye,
bearophile
May 29, 2013
On 05/29/2013 04:11 PM, bearophile wrote:

> Ali Çehreli:
>
>>     writefln("0x%(%x%)", a);
>
> But usually I prefer to show all the zero nibbles:

>      writefln("0x%(%02x%)", a); // Output: 0xa10207b

And only then the output would make sense. Thanks. :)

Ali

May 30, 2013
On Wednesday, 29 May 2013 at 22:03:24 UTC, baws wrote:
> Im trying to learn D, lovely language for a C++ lover. I have a file Im trying to parse, but I need to read the contents as binary data. I also need help understanding how read() works. I'd like to read the first four bytes which identify the file header, I need it to show as a sequence of bytes, how can i output the first 4 bytes to show like 0xFFCF?
>
> With my code, im getting the integer values, If i use cast(byte[]) on read and writefln("Reading header info: 0x%x", bytesRead[0]);
>
> Ill only get the first byte 0xCF.
>
>
> import std.stdio;
> import std.file;
> import std.array;
>
> struct xsdhead{
>     int head1;
>     int head2;
>     int numTables;
> };
>
> immutable int headerInfo1 = 0xFFCF;
> immutable int headerInfo2 = 0x0002;
>
> int main(string [] args){
>     writeln("start");
>     if(args[1] == null){
>         writeln("pass a file");
>         return 0;
>     }
>     auto file = args[1];
>     writeln("Working on ", file);
>
>     auto bytesRead =  cast(byte[]) read(file, 4);
>     writefln("Reading header info: %s", bytesRead);
>     writefln("Address of caret is: 0x%X", &bytesRead);
>
>     return 0;
> }

Erhm, why isnt this compiling guys? all i did was add your suggestions... :/

import std.stdio;
import std.file;
import std.array;

struct xsdhead{
    int head1;
    int head2;
    int numTables;
};

immutable int headerInfo1 = 0xFFCF;
immutable int headerInfo2 = 0x0002;

int main(string [] args){
    writeln("start");
    if(!args[1]){
        writeln("pass a file");
        return 0;
    }
    auto file = args[1];
    writeln("Working on: ", file);

    auto bytesRead =  cast(byte[])read(file, 4);
    writefln("Reading header info: 0x%(%02x%)", bytesRead);

    return 0;
}
May 30, 2013
On 05/29/2013 09:00 PM, baws wrote:

> Erhm, why isnt this compiling guys? all i did was add your
> suggestions... :/

Your code compiles here with dmd 2.062 and v2.063-devel-f6d55a9-dirty. What is the compiler error in your case?

The program has a run time error though: args[1] is an invalid access when args has only one element. Also, you are making an incorrect assumption: Unlike C, the last element of args is not null; such an element simply does not exist. You need a check like this:

    if (args.length != 2) {
        // ...
    }

Ali