A while ago I blogged about a Control system that commits a C Struct to a file on a disk and then reads the file and enters the C Struct data back into the control system.
The operators started noticing inconsistent behaviours.
And so I have had to investigate. After much trial and error I found a quirk that is unique to Windows C Implementations that was causing an issue. It relates to how fwrite and fread write and read data to and from disk.
Basically the file was being written and any special characters it saw that it thought were \n characters e.g. 0A it was adding the (correct for windows) matching carriage return \r 0x0D character. Which effected the offset at which the data was written and made things wrong, really wrong, when it was then opened for reading.
The solution was a change to the fopen calls.
f = fopen(filename, "r"); // before f = fopen(filename, "rb"); // for reading f = fopen(filename, "w"); // before f = fopen(filename, "wb"); // for writing
So once you change the fopen to rb or wb then the fwrite or fread will avoid doing any translation and just write/read the values as they are.
Here is an example of file written with f = fopen(filename, “w”); Note the extra byte at the end of the file.
Here is an example of file written with f = fopen(filename, “wb”);
Notice how although an 0A character appears in the data on line 640 in the first block of bytes fwrite doesn’t try and make it windows line ends by adding a 0D and thus the values maintain their correct offsets and can be read correctly back into the control system.
CR = 0x0D = \015 = \r
LF = 0x0A = \012 = \n