Ich bin auf der Suche nach einer Methode zum Vergleichen und Sortieren von UTF-8-Zeichenfolgen in C++ in einer Groß-und Kleinschreibung, um es in einer custom collation function in SQLite zu verwenden.Fall-insensitive UTF-8-String-Sortierung für SQLite (C/C++)
- Die Methode sollte idealerweise ortsunabhängig sein. Ich werde jedoch nicht den Atem anhalten, soweit ich weiß, ist die Sortierung sehr sprachabhängig, so dass alles, was mit anderen Sprachen als Englisch zu tun hat, auch dann funktioniert, wenn es bedeutet, das Gebietsschema zu wechseln.
- Optionen gehören Standard-C oder C++ Bibliothek oder eine kleine (geeignet für Embedded System) und nicht-GPL (geeignet für ein proprietäres System) BIBLIOTHEK Dritter.
Was ich habe, so weit:
strcoll
mit C locales undstd::collate
/std::collate_byname
sind case-sensitive. (Gibt es Groß- und Kleinschreibung Versionen davon?)Ich versuchte, einen POSIX strcasecmp zu verwenden, aber es scheint not defined für Gegenden zu sein, andere als
"POSIX"
Im POSIX locale, strcasecmp() und strncasecmp() führt einen höheren Wert für niedrigere Conversions und einen Byte-Vergleich aus. Die Ergebnisse sind in anderen Ländereinstellungen nicht angegeben.
Und in der Tat ist das Ergebnis
strcasecmp
nicht zwischen locales auf Linux mit GLIBC ändern.#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)); }
Dies wird gedruckt:
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
Und ja, ich bin mir bewusst, über ICU, aber wir können es nicht auf die Embedded-Plattform verwenden, aufgrund seiner enormous size .
Über Ihr Beispiel mit dem deutschen "ß" -Zeichen (und alle solche Fälle): diese müssen "gelöst" oder anderweitig tausende Male vorher behandelt worden sein, UTF-8 oder nein. MS Word hatte schon immer eine "toggle case" -Funktion - wie funktionierte es in Unicode-Versionen? Wie hat WordPerfect funktioniert? Ich habe das gleiche Problem wie das OP, außer dass ich in Delphi arbeite. Ich habe eine Reihe von Windows sqlite-basierten Apps gesehen, die SELECT (und ich denke ORDER BY) ohne Unterscheidung der Groß- und Kleinschreibung ausführen, egal ob sie in einem deutschen, deutschen oder (in meinem Fall) polnischen Gebietsschema installiert sind. Probieren Sie Firefox :) Wie machen sie das? –
Normalerweise falsch :) Polnisch hat IIRC keine schweren Fälle; Alle Nicht-ASCII-Zeichen, die in Polnisch verwendet werden, basieren auf "ASCII-Zeichen". – MSalters
Mit Ausnahme des Türkisch I-Problems funktioniert der Unicode Case Folding-Algorithmus (http://www.unicode.org/reports/tr44/) bemerkenswert gut. – dalle