Warum transliteriert wprintf russischen Text in Unicode unter Linux in Latein?

Warum transliteriert wprintf russischen Text in Unicode unter Linux in Latein?

Weil die Konvertierung von Breitzeichen gemäß dem aktuell eingestellten Gebietsschema erfolgt. Standardmäßig beginnt ein C-Programm immer mit einem "C"-Locale, das nur ASCII-Zeichen unterstützt.

Sie müssen zuerst zu einem beliebigen russischen oder UTF-8-Gebietsschema wechseln:

setlocale(LC_ALL, "ru_RU.utf8"); // Russian Unicode
setlocale(LC_ALL, "en_US.utf8"); // English US Unicode

Oder zu einem aktuellen Systemgebietsschema (was wahrscheinlich das ist, was Sie brauchen):

setlocale(LC_ALL, "");

Das vollständige Programm wird sein:

#include <stdio.h>
#include <wchar.h>
#include <locale.h>

int main() {
  setlocale(LC_ALL, "ru_RU.utf8");
  wprintf(L"Привет, мир!\n");
}

Was Ihren Code betrifft, der auf anderen Computern unverändert funktioniert, liegt dies daran, wie libc dort funktioniert. Einige Implementierungen (wie musl) unterstützen keine Nicht-Unicode-Locales und können daher breite Zeichen bedingungslos in eine UTF-8-Sequenz übersetzen.


Da das Startgebietsschema Ihres Programms das Standardgebietsschema ist, das C Gebietsschema. Es übersetzt also einen breiten String in C Gebietsschema. C locale verarbeitet weder UTF-8 noch Unicode, daher ist es am besten, wenn Ihre Standardbibliothek breite Zeichen in einen grundlegenden Zeichensatz übersetzt, der in C verwendet wird Gebietsschema.

Sie können das Gebietsschema auf beliebig ändern UTF-8-Gebietsschema und das Programm sollte UTF-8-Strings ausgeben.

Hinweis:(in Implementierung ist mir bekannt) die Codierung des FILE Stream ermittelt und aktuell gespeichert die Stream-Ausrichtung (breit vs. normal) wird gewählt. Denken Sie daran, das Gebietsschema vorher festzulegen alles mit stdout tun (d. h. dies gegen dies).