提问人:Thomas Hedden 提问时间:12/28/2022 更新时间:12/29/2022 访问量:131
在 C 中排序时无法让 strcoll() 使用语言环境
Can't get strcoll() to use locales when sorting in C
问:
我无法让依赖于语言环境的函数(例如 strcoll())在 C 中工作。 我想知道我是否做错了什么和/或如何让它工作。 以下是本书中的一个示例程序: 普林茨、彼得和托尼·克劳福德。2016. 简而言之,第 2 版,第 574 页。北京-波士顿-法纳姆-塞瓦斯托波尔-东京:O'Reilly。国际标准书号-13:978-1-491-90475-6。
#include <stdio.h>
#include <string.h>
#include <locale.h>
int main(void) {
char *samples[ ] = { "curso", "churro" };
setlocale(LC_COLLATE, "es_ES.UTF-8");
int result = strcoll(samples[0], samples[1]);
if(result == 0) {
printf("The strings \"%s\" and \"%s\" are "
"alphabetically equivalent.\n",
samples[0], samples[1]);
} else if(result < 0) {
printf("The string \"%s\" comes before \"%s\" "
"alphabetically.\n",
samples[0], samples[1]);
} else if(result > 0) {
printf("The string \"%s\" comes after \"%s\" "
"alphabetically.\n",
samples[0], samples[1]);
}
return(0);
}
书中说,“curso”应该放在“churro”之前,因为在西班牙语中,“ch”被认为是一个单独的字母,以便按字母顺序排列。但是,当我运行这个程序时,它会打印“curso”在“churro”之后。我不懂西班牙语,但我用我所知道的其他几种语言测试了这个程序,结果总是 strcmp(),这是一个严格的数字比较。
$ gcc --version
gcc (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0
$ locale -a | grep es_ES.utf8
es_ES.utf8
我知道这个问题: 让语言环境函数在 glibc 中工作 作者说,像 strcoll 这样的语言环境相关函数在 glibc 中表现不佳,他正在编写自己的修改。
我错过了什么吗?这根本行不通吗?
答:
“我错过了什么吗?这根本行不通吗?
我认为这归结为您的环境是否识别“es_ES。UTF-8 英寸
请注意,我无法访问 Linux 环境,这削弱了将苹果与苹果进行比较的能力。但我希望以下内容能突出一些可能有帮助的事情......
在Windows上,使用标准的LabWindows/CVI编译器(我的版本基于Clang 3.3),它输出以下内容:
“字符串”curso“按字母顺序排在”churro“之后。”
根据您在使用西班牙语字母化规则时声明的期望,这似乎是不正确的。
我怀疑库的实现和版本有助于我们所看到的。
请注意,后来我检查了以下各项的返回:setlocale
char *new = setlocale(LC_COLLATE, "es_ES.UTF-8");
它返回 NULL,指示以下内容:
“如果 locale 为非 NULL 且可以遵循,则返回指向与指定类别关联的字符串的指针。如果“全部” 选择类别设置,则字符串包含 不同类别的区域设置串联。如果 选择不能被接受,该函数返回一个 NULL 指针和 程序的区域设置保持不变。
表示“es_ES.UTF-8“未被遵守,使语言环境保持不变。
本文对在 C 语言中使用 UTF-8 有一些有趣且相关的见解。以及它与此处看到的区域设置问题的关系。
评论
"es_ES.UTF-8"
您的图书包含过时的信息。自 1994 年以来,西班牙语双字母不再被视为单个字母。请参见 https://rae.es/dpd/abecedario。ch
1994年,西班牙人协会全体会议,1994年,通过对拉丁裔的普遍性、对独立性进行考虑。
(希望不需要翻译)
您还可以在此处查看 Unicode 排序规则数据。这是 glibc 从中获取其排序规则数据的来源。如您所见,有几个排序规则顺序。标准的不考虑和特殊,而传统的则考虑。Glibc 实现了标准排序规则。ch
ll
您可以通过尝试使用带重音字符的字符串来检查西班牙语区域设置排序规则是否正常工作。如果系统正常工作,则这些字母应按排序规则顺序描述的顺序出现(即紧跟在相应的非重音字符之后),如果系统无法正常工作,则应按所有非重音字母(即,如果您忘记调用或不支持区域设置)。演示请注意,在 godbolt 上,GCC 不支持语言环境,而 MSVC 支持(并使用类似 Unix 的语言环境名称启动)。setlocale
如果要测试多字符排序规则,请使用捷克语区域设置 (),它确实可以识别为单个字母,并且在排序规则顺序中位于 h
之后。演示。cs_CZ.UTF-8
ch
评论
上一个:有没有常见的计算机使用大端编码?
评论
The string "curso" comes before "churro" alphabetically.
The string "curso" comes after "churro" alphabetically.
es_ES.UTF-8
ch