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
