The line you cited is badly written. If I understand it correctly, it is taking the address of each inventory and treating it as a cstring. This means that if the compiler decides to place either of the two numbers in inventory before the array in memory (which it is allowed to do), those numbers will be read as the first few characters. Also, you are always writing 20 characters even if you put fewer than 20 into the array, which might cause a bunch of garbage characters to be written.
If you use the << operator, your output is automatically formatted as readable text. The function write is used to write a block of unformatted data, so it saves whatever happens to be in inv[i], not necessarily readable text. If you open the folder for some random program and see lots of files you can't open like .dat, they were probably made with some variation of write; the format may only make sense to that one program.
After read 4 bytes for the int, 28 bytes remaining
After read 8 bytes for the double, 20 bytes remaining
After read 20 bytes for the array, 0 byte remaining.
So it always write 32 bytes,no matter the number of characters in the array is there ?