Say, I want to interpret(i.e. through stdout) a UTF32-encoded string: zß水, taking the examples found on cppreference.
With U prefix, it's straightforward:
printf("%ls",U"zß水")
However, it won't work unless an appropriate "locale" being set before print:
setlocale(LC_ALL, "XXX.UTF-8")
My simplified question is that, why should we use XXX.UTF-8 locale settings, instead of some others like XXX.UTF-32?
My confusion arises when I was testing the code below:
#include <stdio.h>
#include <locale.h>
#include <wchar.h>
#include <uchar.h>
void test2() {
char32_t w_str[] = U"zß水";
printf("wchar width: %d\n", __WCHAR_WIDTH__);
if(__STDC_UTF_32__) printf("confirmed: utf32 used.\n");
printf("(with ' C' locale) wide string is interpreted as: ");
/* set locale */ if (setlocale(LC_ALL, "C") == NULL) perror("setlocale");
if (printf("[%ls]", w_str) == -1) { perror(" ERROR('C' locale)"); clearerr(stdout); }
printf("\n");
printf("(with 'utf8' locale) wide string is interpreted as: ");
/* set locale */ if (setlocale(LC_ALL, "en_US.UTF-8") == NULL) perror("setlocale");
if (printf("[%ls]", w_str) == -1) { perror(" ERROR('utf8' locale)"); clearerr(stdout); }
printf("\n");
}
int main(){test2();}
Along with output:
# gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04)
wchar width: 32
confirmed: utf32 used.
ERROR('C' locale): Invalid or incomplete multibyte or wide character
(with ' C' locale) wide string is interpreted as: [
(with 'utf8' locale) wide string is interpreted as: [zß水]
According to C11-6.4.4.4-9:
Prefix : Corresponding Type
U : char32_t
and C11-6.10.8.2-1:
_ _ STDC_UTF_32 _ _ The integer constant 1, intended to indicate that values of type char32_t are UTF−32 encoded.
My complete question is that, I've already specified an exact UTF32 string literal (and I'm 100% certain that they are exactly UTF32 encoded, by checking the assembly output of the code listed above), isn't it more appropriate to use some locale settings like XXX.UTF-32? If not, then why XXX.UTF-8 is qualified to decode the UTF32 byte sequence?