¿Por qué el siguiente programa
#include <stdio.h> #include <wchar.h> int main() { wprintf(L"Привет, мир!"); }imprimir "Ligustro, mir!" en Linux? Específicamente, ¿por qué translitera el texto ruso en Unicode al latín en lugar de transcodificarlo a UTF-8 o usar caracteres de reemplazo?
Demostración de este comportamiento en Godbolt: https://godbolt.org/z/36zEcG
La versión no ancha printf("Привет, мир!") imprime este texto como se esperaba ("Привет, мир!").
Porque la conversión de caracteres anchos se realiza de acuerdo con la configuración regional actual. De forma predeterminada, un programa C siempre comienza con una configuración regional "C" que solo admite caracteres ASCII.
Primero debe cambiar a cualquier configuración regional rusa o UTF-8:
setlocale(LC_ALL, "ru_RU.utf8"); // Russian Unicode setlocale(LC_ALL, "en_US.utf8"); // English US UnicodeO a una configuración regional del sistema actual (que es probablemente lo que necesita):
setlocale(LC_ALL, "");El programa completo será:
#include <stdio.h> #include <wchar.h> #include <locale.h> int main() { setlocale(LC_ALL, "ru_RU.utf8"); wprintf(L"Привет, мир!\n"); }En cuanto a que su código funcione tal como está en otras máquinas, esto se debe a cómo funciona libc allí. Algunas implementaciones (como musl) no admiten entornos locales que no sean Unicode y, por lo tanto, pueden traducir incondicionalmente caracteres anchos a una secuencia UTF-8.
¿Por qué translitera el texto ruso en Unicode al latín en lugar de transcodificarlo a UTF-8 o usar caracteres de reemplazo?
Porque la configuración regional inicial de su programa es la predeterminada, la configuración regional C Entonces está traduciendo una cadena ancha a la configuración regional C La configuración regional C no maneja UTF-8 ni unicode, por lo que su biblioteca estándar hace lo mejor para traducir caracteres anchos en algún conjunto de caracteres básico utilizado en la configuración regional C
Puede cambiar la configuración regional a cualquier configuración regional UTF-8 y el programa debe generar una cadena UTF-8.
Nota: (en la implementación que conozco) la codificación del flujo de FILE se determina y se guarda en el momento en que se elige la orientación del flujo (ancho frente a normal). Recuerde establecer la configuración regional antes de hacer algo con stdout (es decir, esto frente a esto ).