的手册页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
我的应用程序中的功能使用正确的代码页。
我认为您将不得不遍历它们。在
zsh
:或者在模块中使用其
$langinfo
特殊的关联数组zsh/langinfo
:将列出所有使用 ISO-8859-1 作为charmap 的可用语言环境。
但请注意,
LC_CTYPE
指定charmap / codeset 的类别还包括字符分类:什么是小写字母,什么是标点符号等以及音译(如 所使用的tolower()
),两者都可能因地区/国家而异下一个即使使用相同的代码集。例如,看看 GNU 土耳其语语言环境中的小写字母如何
I
,ı
无论使用什么字符映射(UTF-8、ISO-8859-9...),而i
大多数其他语言环境也使用 UTF-8。您可以查看语言环境源定义,例如:
在 GNU 系统上查看该
LC_CTYPE
类别跨区域设置的差异。您不会在其中找到charmap,这些文件和charmaps 组合的区域设置是使用生成的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
用作charmap 的语言环境,但还需要具有在英国大陆对英国英语或在意大利/德国等讲德语的人有意义的音译规则和字符分类,例如满足:这应该会稍微缩小选择范围。
请注意,
language
andterritory
是非标准的 GNU 扩展,这就解释了为什么你不会在 zsh 中找到它们$langinfo
。GNU libc 文档 (info libc langinfo
) 仅提及:/usr/include/langinfo.h
在我的系统上有:另请参阅
locale -k LC_IDENTIFICATION
,locale -k LC_CTYPE
以获得 GNU 系统上给定语言环境类别支持的关键字列表(locale -kc LC_ALL
过去可以使用,但现在显然不再使用)。