Why printf() can display é
(\u00E9
int UTF-16) and putwchar() can't ?
And what is the right syntax to get putwchar displaying é
correctly ?
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
#include <locale.h>
int main() {
wint_t wc = L'\u00E9';
setlocale(LC_CTYPE, "fr_FR.utf8");
printf("%C\n", wc);
putwchar((wchar_t)wc);
putchar('\n');
return 0;
}
Shell env :
env | grep LC && env | grep LANG
LC_CTYPE=fr_FR.utf8
LANG=fr_FR.UTF-8
GDM_LANG=fr_FR.utf8
Edit
in :
wint_t wc = L'\u00E9'
setlocale(LC_CTYPE, "");
out:
C3 A9 0A E9 0A
in:
wint_t wc = L'\xc3a9';
setlocale(LC_CTYPE, "");
out:
EC 8E A9 0A A9 0A
You cannot mix wide character and byte input/output functions (printf is a byte output function, regardless if it includes formats for wide characters) on the same stream. The orientation of a stream can only be reset with freopen
, which must be done again before calling the byte-oriented putchar
function.
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
#include <locale.h>
int main() {
wint_t wc = L'\u00E9';
setlocale(LC_CTYPE, "");
printf("%lc\n", wc);
freopen(NULL, "w", stdout);
putwchar((wchar_t)wc);
freopen(NULL, "w", stdout);
putchar('\n');
return 0;
}
The fact that the orientation can only be set by reopening the stream indicates that this is not intended to be done trivially, and most programs should use only one kind of output. (i.e. either wprintf/putwchar, or printf/putchar, using printf or wctomb if you need to print a wide character)