我正在寻找一种方法来以不区分大小写的方式比较和排序 C++ 中的 UTF-8 字符串,以便在 SQLite 的自定义排序规则函数中使用它。
- 理想情况下,该方法应该与语言环境无关。但是我不会屏住呼吸,据我所知,排序规则非常依赖于语言,所以任何适用于英语以外的语言的东西都可以,即使这意味着切换语言环境。
- 选项包括使用标准 C 或 C++ 库或小型(适用于嵌入式系统)和非 GPL(适用于专有系统)第三方库。
到目前为止我所拥有的:
strcoll
使用 C 语言环境和std::collate
/std::collate_byname
时区分大小写。(这些有不区分大小写的版本吗?)我尝试使用 POSIX strcasecmp,但似乎没有为其他语言环境定义
"POSIX"
在 POSIX 语言环境中,strcasecmp() 和 strncasecmp() 进行从高到低的转换,然后进行字节比较。结果在其他语言环境中未指定。
而且,事实上,
strcasecmp
在 Linux 上使用 GLIBC 的语言环境之间的结果并没有改变。#include <clocale> #include <cstdio> #include <cassert> #include <cstring> const static char *s1 = "Äaa"; const static char *s2 = "äaa"; int main() { printf("strcasecmp('%s', '%s') == %d\n", s1, s2, strcasecmp(s1, s2)); printf("strcoll('%s', '%s') == %d\n", s1, s2, strcoll(s1, s2)); assert(setlocale(LC_ALL, "en_AU.UTF-8")); printf("strcasecmp('%s', '%s') == %d\n", s1, s2, strcasecmp(s1, s2)); printf("strcoll('%s', '%s') == %d\n", s1, s2, strcoll(s1, s2)); assert(setlocale(LC_ALL, "fi_FI.UTF-8")); printf("strcasecmp('%s', '%s') == %d\n", s1, s2, strcasecmp(s1, s2)); printf("strcoll('%s', '%s') == %d\n", s1, s2, strcoll(s1, s2)); }
这是打印的:
strcasecmp('Äaa', 'äaa') == -32 strcoll('Äaa', 'äaa') == -32 strcasecmp('Äaa', 'äaa') == -32 strcoll('Äaa', 'äaa') == 7 strcasecmp('Äaa', 'äaa') == -32 strcoll('Äaa', 'äaa') == 7
附言