'Wide character input using fgetwc() and fread()
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.
Solution 1:[1]
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.
Solution 2:[2]
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
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | chux - Reinstate Monica |
| Solution 2 |
