I think I discovered a bug but I'm not sure. fread() failed when I use fseek() to set the file pointer to some offset at the offset I set it to, the byte "0x1A" (in hexadecimal) could be found Funny thing is, when I use a hex editor and set the byte at that offset to 0x00 or something else than 0x1A, fread() succeeds If anyone does not completely understand me, feel free to ask. Please help.
I think I might have found it out by myself. Thinking about the EOF byte in Windows, (EOF = End Of File) Windows sees the byte 0x1A as the EOF of a text file, so I might have to open the file in binary mode.
You are absolutely correct. Even in the situations where the soft EOF doesn't mess you up, there are other factors. In text mode, which is the Windows default, but doesn't even exist in *nix systems, a CR is added prior to every LF (newline) during a write. These are stripped out on the read, resulting in one getting the same data one wrote, but seeks/tells are of course not effective. Furthermore, you will find that some append modes will not work properly. Material will be appended, but the original soft EOF will not be removed. It is then not possible to read beyond the original material. I recomend always using binary mode unless you have a compelling reason to do otherwise. Your code will remain portable, as *nix systems will ignore the 'b' in arguments such as "wb" or "rb".
I just decided I'm going to use binary mode everywhere unless I need text mode, just like you do, thanks for great info It's great the UNIX (and alike) systems ignore the stupid (imo) text mode, and also keep the code portable by ignoring the 'b' mode. The Windows text mode read/writes are actually a lot like FTP transfers, files are converted to other system's EOF and line ending usages. Thanks for the info DaWei, you're a quick poster
You can make binary the Windows default by setting a global variable. I believe it's called _fmode. This would not help, of course, if your souce is compiled on a system with the text default. Quite frankly, the text mode thing is a serious bugaboo. The only time it is really necessary is when you are reading files written by another application. If you don't match that application's mode you will wind up with lines that don't wrap or lines that wrap twice, depending upon the direction of mismatch. The expected line endings for Windows, Mac, and *nix, for textual material, are CRLF, CR, and LF. It's unfortunate.
But then indeed, calls to fseek() can be confusing. I usually write my own string functions for correct parsing and text formatting to prevent confusing myself. I'm not even going to try to set the _fmode because I'd probably forget it when compiling on other computers. However, I'm still interested in how to set it? Is it an environment variable?
It's just a global variable (extern int _fmode). One can just write "_fmode = _O_TEXT (or _O_BINARY). Since C++ 2005, though, it is recommended that one use _get_fmode and _set_fmode. You can also just link in Binmode.obj, which will set it to binary EXCEPT FOR operations involving stdin, stdout, and stderr.