SQLiteのカスタム照合関数で使用するために、大文字と小文字を区別しない方法で C++ の UTF-8 文字列を比較およびソートする方法を探しています。
- このメソッドは、理想的にはロケールに依存しない必要があります。しかし、私が知る限り、照合は言語に大きく依存しているため、ロケールの切り替えを意味する場合でも、英語以外の言語で動作するものは何でも動作します。
- オプションには、標準の C または C++ ライブラリ、または小規模(組み込みシステムに適した) および非 GPL (プロプライエタリ システムに適した) サードパーティ ライブラリの使用が含まれます。
私がこれまでに持っているもの:
strcoll
C ロケールでは およびstd::collate
/std::collate_byname
は大文字と小文字が区別されます。(これらの大文字と小文字を区別しないバージョンはありますか?)POSIX strcasecmp を使用しようとしましたが、それ以外のロケールでは定義されていないようです
"POSIX"
POSIX ロケールでは、strcasecmp() と strncasecmp() は上位から下位への変換を行い、次にバイト比較を行います。結果は、他のロケールでは指定されていません。
実際、GLIBC を使用する Linux ではロケール間での結果は
strcasecmp
変わりません。#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
PS