Ben custom collation function in SQLite içinde kullanmak için bir büyük harf duyarlı olmayan şekilde C++ UTF-8 dizeleri karşılaştırmak ve sıralamak için bir yöntem arıyorum.SQLite (C/C++) için büyük/küçük harf duyarsız UTF-8 dize harmanlama
- yöntem ideal yerele bağımsız olmalıdır. Ancak, nefesimi tutmayacağım, bildiğim kadarıyla, harmanlama çok dile bağlıdır, bu yüzden İngilizce'yi başka bir dilde çalıştıran herhangi bir şey, yerelleri değiştirmek anlamına gelse bile.
- Seçenek C ya da C++ kütüphanesi ya da bir küçük (gömülü sistemi için) ve GPL olmayan (özel bir sistem için uygundur) üçüncü taraf kitaplığı kullanılarak, içermektedir. var bugüne kadar ne
: C yerel ayarlar ile
strcoll
vestd::collate
/std::collate_byname
harf duyarlıdır.Bir POSIX strcasecmp kullanmaya çalıştı (bunlardan küçük harf duyarsız versiyonları? Var mıdır), ancak
"POSIX"
POSIX yerelinde, strcasecmp işlevindeki dışındaki yerler için not defined gibi görünüyor() ve strncasecmp(), daha düşük dönüşümleri yapar, daha sonra bayt karşılaştırması yapar. Sonuçlar diğer lokallerde belirtilmemiş.
Ve, gerçekten,
strcasecmp
sonucu glibc ile Linux üzerinde yerel ayarlar arasında değişmez.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
Ve evet, ben ICU hakkında farkındayım, ancak biz nedeniyle enormous size için gömülü platformda kullanamaz:#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));
}
Bu yazdırılır .
Örneğiniz, Alman "ß" karakteri (ve bu kadar çok sayıda vaka) ile ilgili olarak: bunlar, "çözülmüş" olmalı ya da UTF-8 veya daha önce binlerce kez daha önce yapılmalıdır. MS Word, her zaman bir "geçiş durumu" özelliğine sahipti - Unicode öncesi sürümlerde bu karakter üzerinde nasıl çalıştı? WordPerfect nasıldı? Delphi'de çalışmak dışında OP ile aynı sorunu yaşıyorum. Bir ingilizce, Almanca veya (benim durumumda) Lehçe yerel ayarında yüklü olsun, büyük/küçük harf duyarlı SELECT (ve SİPARİŞ BY) gerçekleştiren bir dizi Windows sqlite tabanlı uygulamalar gördüm. Firefox'u Dene :) Bunu nasıl yapıyorlar? –
Genellikle yanlış :) Lehçe, IIRC sert vakası yoktur; Lehçe'de kullanılan tüm ASCII olmayan karakterler "ASCII karakterlerine dayanır". – MSalters
Türkçe I sorunu hariç, Unicode Vaka Katlama algoritması (http://www.unicode.org/reports/tr44/) oldukça iyi çalışıyor. – dalle