Search code examples
ciobinaryfiles

Writing 2D array into binary file in C (getting strange results)


I'm using this code to write the file:

FILE *f = fopen("out/solution.raw", "wb");
int i, j;
//SIZE = 512
for(i = 0; i < SIZE; i++)
{
    fwrite(matrix[i], 1, SIZE, f);
}   

fclose(f);

The problem is that when I open the file, it 3 '0' between the numbers, here are 2 screenshots to help you understand what I mean:

This is what I should be getting:

This is what I should be getting:

And this is what I'm getting:

My output

As you can see my code is correctly writing each number, but there are three 0 between each number and I have no idea why.

I've also tried this:

fwrite(matrix[i], sizeof(matrix[i][0]), SIZE, f);

But none seems to work, any help would be greatly appreciated.


my matrix is declared as a 2D array of ints, as I need to do some operations with those numbers:

matrix = (int**)malloc(SIZE * sizeof(int*));
for (i = 0; i < SIZE; i++)
{
    matrix [i] = (int*)malloc(SIZE * sizeof(int*));
}

I've tried your solution but I can't assign an unsiged char to an int, so I've tried casting it and I get this warning:

cast from pointer to integer of different size.

unsigned char to_write;
for(i = 0; i < SIZE; i++)
{
    to_write = (unsigned char)matrix[i];
    fwrite(&to_write, 1, 1, f);
}   

(code used)

After that this is what I'm getting:

enter image description here

And btw, my data is unsigned.


Solution

  • matrix[i] is a pointer on 32-bit integers. Even if you assign values that hold in 8 bits, that doesn't "compress" the data when you're writing to a binary stream (plus you probably don't write the 512 values but only 512/4 = 128 values)

    Your machine is little endian, so you get the LSB first, then 3 zeros, for each value.

    So change the type of matrix[i] from int32_t * to char * or unsigned char * depending on what you need, make sure your values are in 8-bit range, and you can use fwrite like you're planning to.

    If you cannot change the data type of matrix, use a loop to convert the values

    for(i = 0; i < SIZE; i++)
    {
        uint8_t to_write = matrix[i];  // assign/truncate for 0/255 range
        fwrite(&to_write, 1, 1, f);
    }   
    

    if your data is signed, you have to use int8_t. But in that case, you're not going to be able to write a0 as 160.

    EDIT: your edit shows the real type of matrix. matrix[i] is a pointer on data, so you need to use a double loop to dump it, else you're copying the address of the array, not the value

    for(i = 0; i < SIZE; i++)
    {
       const int *row = matrix[i];
       for(j = 0; j < SIZE; j++)
       {
           uint8_t to_write = row[j];  // assign/truncate for 0/255 range
           fwrite(&to_write, 1, 1, f);
       }
    }