매뉴얼 페이지setlocale
언어 코드와 문자 인코딩 이름만으로도 적절한 로케일을 설정할 수 있는 것 같습니다.
로케일 이름은 일반적으로 언어[_territory][.codeset][@modifier] 형식을 취합니다. 여기서 언어는 ISO 639 언어 코드이고, 지역은 ISO 3166 국가 코드이며, 코드 세트는 ISO-와 같은 문자 세트 또는 인코딩 식별자입니다. 8859-1 또는 UTF-8.
그러나 빠른 테스트를 통해 로케일 이름의 "수정자" 부분만 선택 사항임을 알 수 있습니다.
void tryLocale(const char * locid)
{
char * result = std::setlocale(LC_CTYPE, locid);
std::cout << locid << " = " << (result ? result : "fail") << std::endl;
}
int main()
{
tryLocale("de"); // de = fail
tryLocale("de_DE"); // de_DE = fail
tryLocale("de_DE.CP1252"); // de_DE.CP1252 = de_DE.CP1252
tryLocale("de.CP1252"); // de.CP1252 = fail
tryLocale(".CP1252"); // .CP1252 = fail
}
내 문제는 필요한 인코딩 이름(예: ISO-8859-1
)만 알고 있고 아마도 언어 코드(예: )를 생각해낼 수 있다는 것입니다 en
. 적절한 국가 이름(예: )을 찾는 방법을 모르고 US
국가에 관심이 없습니다. 단지 tolower
내 애플리케이션의 기능과 같은 기능이 올바른 코드 페이지를 사용하기를 원할 뿐입니다.
답변1
나는 당신이 그들을 순환해야한다고 생각합니다. 존재하다 zsh
:
for l (${(f)"$(locale -a)"})
[[ $(LC_ALL=$l locale charmap) = ISO-8859-1 ]] && print -r -- $l
또는 $langinfo
특수 연관 배열을 사용하여 모듈에서 동일한 작업을 수행합니다 zsh/langinfo
.
zmodload zsh/langinfo
for LC_ALL (${(f)"$(locale -a)"})
[[ $langinfo[CODESET] = ISO-8859-1 ]] && print -r -- $LC_ALL
ISO-8859-1을 문자표로 사용하는 사용 가능한 모든 로캘이 나열됩니다.
그러나 LC_CTYPE
문자 맵/코드 세트를 지정하는 범주에는 문자 분류(소문자, 구두점 등)와 음역(사용된 대로)도 포함되며 tolower()
둘 다 지역/국가에 따라 다를 수 있습니다. 동일한 코드 세트를 사용하더라도 다음 코드도 마찬가지입니다.
예를 들어, 사용된 문자 매핑(UTF-8, ISO-8859-9...)에 관계없이 GNU 터키어 로케일의 소문자 형식을 살펴보고 I
UTF -8을 사용하는 대부분의 다른 로케일에서도 마찬가지입니다.ı
i
다음과 같은 로케일 소스 정의를 볼 수 있습니다.
(cd /usr/share/i18n/locales && pcregrep -Me '(?ms)^LC_CTYPE.*?^END' -- *)
GNU 시스템의 이 범주에서 LC_CTYPE
로케일 간 차이점을 확인하세요. 여기서는 문자 맵을 찾을 수 없습니다. 이러한 파일 조합에 대한 로케일과 문자 맵은 를 사용하여 생성됩니다 localedef -i thosefiles -f charmap
. 단 일부 조합만 의미가 있습니다. /usr/share/i18n/SUPPORTED
목록은 참고자료를 참조하세요.
예를 들어 en_GB
시스템의 로케일은 및 localedef -i locales/en_GB -f charmaps/ISO-8859-1.gz
를 사용하여 en_GB.UTF-8
생성 될 수 있습니다 localedef -i locales/en_GB -f charmaps/UTF-8.gz
.
따라서 여기에서 문자 맵 역할을 하는 로케일을 찾아야 할 수도 있지만 ISO-8859-1
영국 영어 또는 이탈리아어/독일어와 같은 독일어 사용자가 영국 본토에서 이해할 수 있는 음역 규칙 및 문자 분류도 필요합니다.
[[ $(locale language) = 'British English' &&
$(locale territory) = 'United Kingdom' &&
$(locale charmap) = ISO-8859-1 ]]
이렇게 하면 선택 범위가 약간 좁아집니다.
language
및 는 territory
비표준 GNU 확장입니다. 이는 zsh( ) $langinfo
에 대한 .GNU libc 문서에서 다음만 언급하는 이유를 설명합니다.info libc langinfo
"langinfo.h" 파일에는 더 많은 기호가 정의되어 있지만 공식적인 기호는 없습니다. 이를 사용하는 것은 이식 가능하지 않으며 반환 값의 형식이 변경될 수 있습니다. 그러므로 우리는 당신이 그것들을 사용하지 않는 것을 권장합니다.
/usr/include/langinfo.h
내 시스템에는 다음이 있습니다.
_NL_IDENTIFICATION_LANGUAGE,
_NL_IDENTIFICATION_TERRITORY,
GNU 시스템에서 특정 로케일 범주에 대해 지원되는 키워드 목록 도 참조하십시오 locale -k LC_IDENTIFICATION
( 이전에는 작동했지만 더 이상 작동하지 않는 것 같습니다).locale -k LC_CTYPE
locale -kc LC_ALL