One of the most common problems when porting file I/O code from other operating systems to Windows is that the C runtime on Windows allows files to be opened in two modes: text and binary. This distinction originated because text files on Windows use a carriage return ('\r') and a linefeed ('\n') to indicate a newline, while on Unix only a linefeed is used. To ensure that ANSI C requirements are met, the C runtime translates CR+LF line endings to LF when reading and writing text files. However, if your program operates on binary files (e.g. an executable) then this translation must be disabled by opening the file in binary mode, for example:

FILE *fp = fopen("filename.abc", "rb");

The "b" option is ANSI C compliant, so this code will work on Unix too. The main difficulty with porting is that text mode is the default so any program that works on binary files must be modified. Instead of modifying every call to fopen(), there are Windows-specific ways to make binary mode the default:

1) You could add /mingw/lib/binmode.o to the objects when you build the executable. This has the effect of making binary-mode file translation the default (except that preopened files stdin, stderr, stdout remain text).

Setting _CRT_fmode also has the effect of making stdin. stderr, stdout binary mode which is useful if you are redirecting them to files.

If you have changed the default to binary mode, you can still open a file as text as follows:

FILE *fp = fopen("filename.txt", "rt");

However, this is not ANSI C compliant. As a long term solution though, it is better to modify each call to fopen(), and this also allows a mixture of binary and text files to be used in a single program in an ANSI C compliant way.

You will also want to force binary mode if you need to rely on the in-memory representation of the file being the same as that on disk. For example to seek() to a location found in a string read from file. However it is probably good practice not to do so. -- SteveLee

Owner: "195.194.22.45" Last edited on January 4, 2006 9:04 pm by "PatLaVarre"