When reading a wide character from a FILE
stream, can fgetwc()
and fread()
be used interchangeably?
It's tempting to assume that fgetwc()
might work like this:
wint_t fgetwc(FILE *src) {
wchar_t c;
size_t n_bytes = fread(&c, sizeof (wchar_t), 1, src);
return (n_bytes == sizeof (wchar_t)) ? c : WEOF;
}
Although, I'm suspecting that such implementation might fail on big endian systems.
CodePudding user response:
can
fgetwc()
andfread()
be used interchangeably?
Not easily.
Once a narrow or wide read/write occurs, the stream orientation is set to read wide or narrow characters.
fread()
is a narrow function. Others: fgetc, fgets, fprintf, fputc, fputs, fread, fscanf, fwrite, getc, getchar, printf, putc, putchar, puts, scanf, ungetc, vfprintf, vfscanf, vprintf, and vscanf
)
fgetwc()
is a wide one. Others: fgetws, getwc, getwchar, fwscanf, wscanf, vfwscanf, vwscanf, fputwc, fputws, putwc, putwchar, fwprintf, wprintf, vfwprintf, vwprintf
.
Use fwide()
or freopen()
to change the orientation.
Best not to mix narrow/wide functions else an error (encoding) may occur.
endian
is a separate issue. OP's fgetwc()
does not take into account orientation nor certainly handle endian issues well.
CodePudding user response:
fgetwc
does not "read a wide character". It reads a multibyte character (these days, usually a UTF-8 sequence) and converts it into a wchar_t
. Similarly, fputwc
takes a wchar_t
and writes it out as a multibyte sequence.
If you want to actually read or write wchar_t
units, you need to use fread
or fwrite
, and you should probably open the file in binary mode in case one of the bytes in the wchar_t
would undergo special handling in a text file.
fread
and fwrite
are considered byte-oriented, so they cannot be mixed with wide-oriented I/O.
Note: apparently, the Windows library implementation of fgetwc and fputwc does read and write wchar_t
units if the file was opened in binary mode. With files opened in text mode, the behaviour is as described above. See the MSDN documentation