Search code examples
cfwrite

fwrite outputting byte as a short


I am trying to write the following array to file:

char * data = malloc(4);
data[0] = 0x6f;
data[1] = 0x45;
data[2] = 0x23;
data[3] = 0x01;

opening code:

FILE *fp = fopen("output.txt", "wb");
if (fp != NULL){ 
    ...

I have tried to output the data in these ways:

fwrite(data, 4, sizeof(char), fp);
fwrite(data, sizeof(char), 4, fp);

for(i = 0; i < 4; i++){
    fwrite(data + i, 1, 1, fp);
}

...

But EVERY single way that I use fwrite my output file looks like this:

hexdump output.txt
0000000 060f 0405 0203 0001

edit: for reference, I want the output to look like this:

0000000 6f45 2301

end edit

closing code:

fclose(fp);

Can someone please explain to me what is going on before I go insane?

Edit: I'm a moron. Thank you for trying to help me out. The data was being generated in a way that I thought the container was as above, but actually each char was getting a portion of the hex. I.e. data[0] was 0x6, data[1] was 0xf. Therefore when fwrite was writing to file, it was just filing in the gaps, 0xf is actually 0x0f, etc. Sorry to waste everyone's time.


Solution

  • It is unclear where the precise problem is from your question. The allocations and assignments produce the desired output. What's missing is the validation that what you have attempted actually succeeded.

    For example, the following code (using your allocation, assignment, and fwrite) produced your desired output:

    #include <stdio.h>
    #include <stdlib.h>
    
    int main (int argc, char **argv) {
    
        size_t n;
        char *data = malloc (4);
        FILE *fp = argc > 1 ? fopen (argv[1], "wb") : stdout;
    
        if (!fp) {      /* validate file open for reading */
            fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
            return 1;
        }
    
        if (!data) {    /* validate allocation succeeded */
            fprintf (stderr, "error: virtual memory exhausted.\n");
            return 1;
        }
    
        data[0] = 0x6f;
        data[1] = 0x45;
        data[2] = 0x23;
        data[3] = 0x01;
    
        /* write / validate write size */
        if ((n = fwrite (data, sizeof *data, 4, fp)) != 4) {
            fprintf (stderr, "error: fwrite failure.\n");
            return 1;
        }
    
        if (fclose (fp) == EOF) {  /* validate close after write */
            fprintf (stderr, "error: on file stream close.\n");
            return 1;
        }
    
        free (data);
    
        return 0;
    }
    

    Example Output File

    $ ./bin/frwitebytes dat/databytes.dat
    
    $ hexdump -Cv dat/databytes.dat
    00000000  6f 45 23 01                                       |oE#.|
    00000004
    

    or precisely the hexdump format you are looking for:

    $ hexdump dat/databytes.dat
    0000000 456f 0123
    0000004
    

    Look things over and let me know if I have misinterpreted your question.