strcmp()和strcoll()之间有什么区别
What is the difference between strcmp() and strcoll()?
我试着理解它们,但除了strcoll()
之外,我没有发现任何差异,这个参考文献说它是
根据LC_COLLATE类别定义的当前区域设置比较两个以null结尾的字符串。
转念一想,我知道我在问另一个问题来获得详细的答案,对于C和C++来说,这个语言环境到底是什么?
strcmp()
逐个获取字符串的字节,并按字节数进行比较。
strcoll()
获取字节,使用区域设置对其进行转换,然后比较结果。转换根据语言重新排序。在法语中,重音字母在非重音字母之后。所以é在e之后。但是,é在f之前。strcoll()
做对了。CCD_ 5不太好。
但是,在许多情况下,strcmp()
就足够了,因为您不需要显示按使用的语言(区域设置(排序的结果。例如,如果您只需要快速访问由字符串索引的大量数据,则可以使用由该字符串索引的映射。使用通常非常慢的strcoll()
(至少与strcmp()
相比(对那些进行排序可能是完全无用的
有关字符的详细信息,您可能还想查看Unicode网站。
就语言环境而言。默认情况下,它被设置为"C"(或多或少,没有区域设置(。一旦您选择了一个位置,就会相应地设置区域设置。您还可以设置LC_LOCALE环境变量。实际上有很多这样的变量。但通常情况下,您使用预定义的函数,这些函数会自动考虑这些变量,并为您做正确的事情。(即格式化日期/时间、格式化数字/度量值、计算大小写等(
由于某种原因,在我测试的所有unicode语言环境中,在几个不同版本的glibc上,strcoll((对任何两个平假名都返回零。这打破了sort、uniq以及以某种方式与字符串顺序交互的所有内容。
$echo-e-n'い\nろ\nは\nに\nほ\nへ\nと\n'|sort|uniq
い
它只是坏得无法修复。来自世界不同地方的人可能对是否い'应放在"之前或之后ろ',但没有一个理智的人会认为他们是一样的。
不,将您的语言环境设置为日语并不重要:
$LC_ALL=ja_JP.utf8 LANG=ja_JPEG.utf8 LC_COLLATE=ja_JP.utf8 echo-e-n'い\nろ\nは\nに\nほ\nへ\nと\n'|sort|uniq
い
在一些官方邮件列表中有过讨论,但你猜怎么着,那是在2002年,因为人们不在乎,所以它从未被修复:https://www.mail-archive.com/linux-utf8@nl.linux.org/msg02658.html
这个错误在某一天发生在我们身上,最终我们唯一的出路就是将校勘地点设置为";C";并且依赖于utf-8编码的良好特性。这是一次可怕的经历,因为一个人不应该真正在";C";处理所有日语数据时的语言环境。
所以为了你的理智,不要直接使用strcoll。一个更安全的变体可能是:
int safe_strcoll(const char *a, const char *b)
{
int ret = strcoll(a, b);
if (ret != 0) return ret;
return strcmp(a, b);
}
万一strcoll((决定搞砸你。。。
编辑:我只是出于好奇重复了这个实验,我目前的系统(glibc 2.29(现在运行起来没有问题。当地语言也不重要。
- 向量 <int> a {N, 0} 和 int arr a[N] = {0} 的时间复杂度有什么区别
- 在 .h 文件中的类中声明静态变量和在.cpp文件中声明"global"变量有什么区别
- 我是C++编程的新手,这些代码之间有什么区别,我应该使用哪一个
- 返回常量对象引用 (getter) 和仅返回字符串有什么区别?
- Qt:remove() 和 rmdir() 有什么区别
- 这 4 个 lambda 表达式之间有什么区别?
- 将向量作为类>(值)<向量启动和向量<类>[值]有什么区别
- typedef 枚举和枚举类有什么区别?
- &C::c 和 &(C::c) 有什么区别?
- ascii 和 unicode 在处理级别有什么区别吗?
- C 中的常量限定符和 C++ 中的常量限定符有什么区别?
- "ABC" 和 "ABC" ) 在C++中有什么区别?
- 空指针常量 (nullptr)、空指针值和空成员指针值之间有什么区别?
- 引用捕获和在 lambda 中通过引用发送参数有什么区别 (C++)
- 两种访问I2C总线的方法有什么区别?
- 两种模板示例有什么区别?
- 这两种C++语法之间有什么区别?
- lua 5.0.2 模块和 5.3.5 有什么区别?
- C++中"typedef"、"using"、"namespace"和"using namespace"有什么区别?
- std::enable_if 和 std::enable_if_t 有什么区别?