When using fgetc
, fputc
, fgets
and fputs
for a file, do I need to ensure that I have open
ed the file in text mod
[edit after a try under windows using mingw]
The difference between text and binary mode only exist under Windows and not only concern fwrite and fread but also fgetc/fputc/.../_read
/_write
On text mode if a file contains the sequence \r\n only the \n is get when you read like if the file does not contain the \r. In binary mode the two characters are return. Note fread Microsoft Docs and _read Microsoft Docs speak about that case but unfortunately nothing is said for fgetc in fget fgetwc Microsoft Docs
When writing if the stream is opened in text mode each \n is written as a \r\n pair. Note the replacement has no effect on the size return by fwrite. In binary mode \n is written unchanged, there is no \r added. Note fwrite Microsoft Docs and _write Microsoft Docs speak about that case but unfortunately nothing is said for fputc in fputc fputwc Microsoft Docs
Fortunately in text mode under Windows read and write functions are symmetric, when you write in text mode foo\nbar then you read the produced file still in text mode you get foo\nbar, but there is foo\r\nbar into the file.
So
When using fgetc, fputc, fgets and fputs for a file, do I need to ensure that I have opened the file in text mode not binary mode?
the mode has an impact
When using fread and fwrite, do I need to opened the file in binary mode not text mode?
Like for the other functions it is your choice, but if the file is also read/write by an other tool it is may be better to open in text mode in case these tools expect a \r before a \n when reading or producing the pair when writing. Of course you can also open in binary mode and explicitly write a \r before a \n by yourself.
If the file is only for you using C to read/write it may be better to always open in binary mode to have in the file only what you explicitly ask for to have. This is enforced if you use ftell/fseek.
As said in ftell Microsoft Docs ftell and _ftelli64 may not reflect the physical byte offset for streams opened in text mode, because text mode causes carriage return-linefeed translation.
It is worst concerning fseek, as said in fseek Microsoft Docs :
for streams opened in text mode, fseek and _fseeki64 have limited use, because carriage return-linefeed translations can cause fseek and _fseeki64 to produce unexpected results. The only fseek and _fseeki64 operations guaranteed to work on streams opened in text mode are:
Seeking with an offset of 0 relative to any of the origin values.
Seeking from the beginning of the file with an offset value returned from a call to ftell when using fseek or _ftelli64 when using _fseeki64.
No. All stdio input and output functions are defined in terms of repeated calls to fgetc
or fputc
. Aside from POSIX requirements on top (mainly locking being for the whole larger operation rather than at the individual fgetc
/fputc
granularity), there is no difference between calling fputc
or fgetc
in a loop yourself, or doing the equivalent with fwrite
or fread
.
If the C implementation you use treats text files differently from binary, that treatment applies no matter which functions you use to perform the operations.