0

I have an array of long values and I would like to save them to a file called "Longs.myData". I expected my file to have a size of 24 bytes since the array only has 3 indices. However, I am getting a file that is 192 bytes. Is there a way to save my data and get a file that takes up 24 bytes? P.S I know that saving the file as a .txt gives a file size of 33 bytes. Thank you!

 #include <stdio.h>
 #include <stdlib.h>    

void CreateFile()
{
    //Array containing my data
    long data[3];
    data[0] = 2147483644;
    data[1] = 2147483645;   
    data[2] = 2147483646;   
    
    //Initializing a pointer to FILE
    FILE *myFilePointer;
    
    //Creating a new file "Longs.myData"
    myFilePointer = fopen("Longs.myData", "wb");
    
    //Error handling
    if(myFilePointer == NULL){exit(1);}
    
    //Save array to file
    fwrite(data, sizeof(long), sizeof(data), myFilePointer);
    
    //sizeof(long) = 8, sizeof(data) = 24 //Total 192
    printf("%d %d \n", (int) sizeof(long), (int) sizeof(data));
    fclose(myFilePointer);
    
}

int main()
{
    CreateFile();
    return 0;
}
murage kibicho
  • 546
  • 5
  • 14
  • `fwrite()` will write x items of data, each y bytes in size. `sizeof(data) == sizeof(long)*3`, so you're effectively writing `sizeof(long) * sizeof(long) * 3` bytes to the file, which may or may not segfault. – vmt Dec 13 '20 at 23:32
  • This [question / answer](https://stackoverflow.com/questions/17598572/read-and-write-to-binary-files-in-c) address this topic. Correct me if I am wrong please. – ryyker Dec 13 '20 at 23:42

1 Answers1

1

At this declaration:

long data[3];  

memory for all three elements of data is created as one contiguous block. And per the 2nd and 3rd arguments of the following prototype of fwrite(),

size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)  
  1. size − This is the size in bytes of each element to be written.
  2. nmemb − This is the number of elements, each one with a size of size bytes.

The total number of bytes written is given by multiplying arguments 2 & 3.

So in the following syntax the combined argument are simply representing too many bytes:

fwrite(data, sizeof(long), sizeof(data), myFilePointer);

Breaking it down...
Total bytes to write are given by

sizeof(long)*sizeof(data)
//    8     *    3 * 8  (sizeof(data) == 3 array elements*sizeof(long))
//    8     *      24  = 192

1 factor of sizeof(long) too many. If sizeof(long) == 8, then the math is:

The arguments can be written several way to get the correct count. Using char (byte) as the fundamental element, and given sizeof(char) is always 1:

fwrite(data, 1, sizeof(data), myFilePointer);
//           1    3*sizeof(long) ==>  1*3*8   == 24 
 

Using long as the fundamental element, and the array size (3) as count of elements

fwrite(data, sizeof(long), sizeof(data)/sizeof(data[0]), myFilePointer);
//               8                3  ==>  8*3 == 24

An aside: although not required, when working with binary files it is preferable to use unsigned types:

"unsigned is used to avoid signed [arithmetic] to get in the way, and because it best represents binary contents (a value between 0 and 255)"

(from here)

ryyker
  • 22,849
  • 3
  • 43
  • 87