writing binary files

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

writing binary files

larcky
This post has NOT been accepted by the mailing list yet.
Hello
Is Pike able to write binary files?  Something like this in C:

#include <stdio.h>
int main()
{
    int n = 7;
    int arr[] = { 4, 5, 9, 12, 255, 0, 8 };
    FILE *fout = fopen("foo.bin", "wctb");

    for (int i = 0; i < n; ++i) {
        fwrite(arr+i, 1, 1, fout);
    }
    fclose(fout);
    return 0;
}

Thanks.

Reply | Threaded
Open this post in threaded view
|

Re: {Spam?} writing binary files

H. William Welliver III-2
Something like this should work (though is probably not the most
efficient approach):

   Stdio.File f = Stdio.File("foo.bin", "wct");
   array arr = ({ 4, 5, 9, 12, 255, 0, 8 });
   for(int i = 0; i < sizeof(arr); i++)
     f->write(String.int2char(arr[i]));
   f->close();

   Stdio.read_file("foo.bin");
(2) Result: "\4\5\t\f\377\0\b"


You can probably find a use of sprintf() that can convert the whole int
array into a string of chars in one go... look at the [] operators in
the sprintf() documentation.

Hope this helps!

Bill

On 2017-05-01 05:52, larcky wrote:

> Hello
> Is Pike able to write binary files?  Something like this in C:
>
> #include <stdio.h>
> int main()
> {
>     int n = 7;
>     int arr[] = { 4, 5, 9, 12, 255, 0, 8 };
>     FILE *fout = fopen("foo.bin", "wctb");
>
>     for (int i = 0; i < n; ++i) {
>         fwrite(arr+i, 1, 1, fout);
>     }
>     fclose(fout);
>     return 0;
> }
>
> Thanks.
>

Reply | Threaded
Open this post in threaded view
|

Re: {Spam?} writing binary files

larcky
This post has NOT been accepted by the mailing list yet.
Hi thanks for reply!
That example was perfect but also as you suggested...

int main()
{
    Stdio.File f = Stdio.File("foo.bin", "wct");
    array(int) arr = ({ 4, 5, 9, 12, 255, 0, 8 });
    f->write( sprintf("%{%c%}", arr) );
    f->close();
    return 0;
}

Pike=awesome
Reply | Threaded
Open this post in threaded view
|

Re: {Spam?} writing binary files

Pontus Rodling-2
Hi,

There's an even easier way if you have an array of ints.
Casting the array to a string will turn each element of the array into a
character:

> array(int) arr = ({ 4, 5, 9, 12, 255, 0, 8 });
> (string)arr;
(1) Result: "\4\5\t\f\377\0\b"

So just f->write((string)arr) would work.


The same thing also works in reverse:

> (array)"\4\5\t\f\377\0\b";
(3) Result: ({ /* 7 elements */
                4,
                5,
                9,
                12,
                255,
                0,
                8
            })


Most of the time I typically just operate on indexes in the string when
dealing with binary formats, like:

> string s = "abc";
> s[1] = 'd';
> s;
(7) Result: "adc"


Range operators are also incredibly helpful, and are applicable to both
strings and arrays (great for parsing binary formats):

> string s = "potato";
> s[2..];
(8) Result: "tato"
> s[2..3];
(9) Result: "ta"
> s[2..<1];
(10) Result: "tat"
> s[1..<2];


An important thing to note as well is that a character is not limited to
0-255, larger values are allowed to support unicode strings, or
'widestrings'.
Only thing to remember is that a widestring would need to be encoded
when writing to a file, for example using UTF-8.

> string a = "\u1234";
> a[0];
(17) Result: 4660
> string_to_utf8(a);
(18) Result: "\341\210\264"


Happy file writing :)

Best regards,
Pontus

On 05/02/2017 06:04 AM, larcky wrote:

> Hi thanks for reply!
> That example was perfect but also as you suggested...
>
> int main()
> {
>     Stdio.File f = Stdio.File("foo.bin", "wct");
>     array(int) arr = ({ 4, 5, 9, 12, 255, 0, 8 });
>     *f->write( sprintf("%{%c%}", arr) );*
>     f->close();
>     return 0;
> }
>
> Pike=awesome
>
>
>
> --
> View this message in context: http://pike.1058338.n5.nabble.com/writing-binary-files-tp5713245p5713247.html
> Sent from the Pike - User mailing list archive at Nabble.com.
>

Reply | Threaded
Open this post in threaded view
|

Re: {Spam?} writing binary files

larcky
This post has NOT been accepted by the mailing list yet.
A small cross-assembler project in the works.
All those tricks will come in handy - thanks Pontus :)
Reply | Threaded
Open this post in threaded view
|

Re: {Spam?} writing binary files

Martin Nilsson (Coppermist) @ Pike (-) importmöte för mailinglistan
In reply to this post by larcky
Also just cast to string.

> (string)({65,66,67,254});
(5) Result: "ABC\376"