programing

왜 wprintf는 리눅스에서 유니코드의 러시아어 텍스트를 라틴어로 번역합니까?

newstyles 2023. 10. 6. 20:58

왜 wprintf는 리눅스에서 유니코드의 러시아어 텍스트를 라틴어로 번역합니까?

왜 다음 프로그램이

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

int main() {
  wprintf(L"Привет, мир!");
}

리눅스에서 "Privet, mir!"를 인쇄할 수 있습니까?특히 UTF-8로 변환하거나 대체 문자를 사용하는 것이 아니라 유니코드의 러시아어 텍스트를 라틴어로 변환하는 이유는 무엇입니까?

Godbolt에서의 이러한 행동 시연 : https://godbolt.org/z/36zEcG

비와이드 버전printf("Привет, мир!")예상대로 이 텍스트를 인쇄합니다("п ривет, мир!").

현재 설정된 로케일에 따라 와이드 문자 변환이 이루어지기 때문입니다.기본적으로 C 프로그램은 항상 ASCII 문자만 지원하는 "C" 로케일로 시작합니다.

먼저 러시아어 또는 UTF-8 로케일로 전환해야 합니다.

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

또는 현재 시스템 로케일(필요한 것일 가능성이 높음)로:

setlocale(LC_ALL, "");

전체 프로그램은 다음과 같습니다.

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

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

당신의 코드가 다른 기계에서 그대로 작동하는 것에 관해서는, 이것은 libc가 그곳에서 작동하는 방식 때문입니다.musl과 같은 일부 구현은 Unicode가 아닌 로케일을 지원하지 않으므로 무조건 넓은 문자를 UTF-8 시퀀스로 변환할 수 있습니다.

UTF-8로 변환하거나 대체 문자를 사용하는 것이 아니라 유니코드의 러시아어 텍스트를 라틴어로 변환하는 이유는 무엇입니까?

프로그램의 시작 로케일이 기본 로케일이기 때문에C로캘.그래서 그것은 넓은 문자열을 번역하고 있습니다.C로캘.C로케일은 UTF-8이나 유니코드를 처리하지 않으므로 표준 라이브러리에서 넓은 문자를 에서 사용되는 기본 문자 집합으로 변환하는 것이 가장 좋습니다.C로캘.

로케일을 UTF-8 로케일로 변경할 수 있으며 프로그램은 UTF-8 문자열을 출력해야 합니다.

참고: (내가 알고 있는 구현에서) 의 인코딩.FILE스트림 방향(넓게 대 보통)을 선택할 때 스트림이 결정되고 저장됩니다.작업을 수행하기 에 로케일을 설정해야 합니다.stdout(즉, 이것이것).

언급URL : https://stackoverflow.com/questions/65494406/why-does-wprintf-transliterate-russian-text-in-unicode-into-latin-on-linux