Seite 1 von 1
[C++] u16string zu lower case
Verfasst: 10.03.2016, 15:24
von Raphael
Hi,
ich versuche gerade eine simple Autovervollständigung mit einer Baumdatenstruktur zu verwirklichen. Diese selbst funktioniert, nur möchte ich noch die Wörter aus dem Dictionary in Kleinbuchstaben konvertieren, bzw. auch Anfragen an den Algorithmus in Kleinbuchstaben umwandeln. Allgemein finde ich die Nutzung von Unicode mit C++11 ziemlich anstrengend und online ist recht wenig zu finden. Intern benutze ich char16_t und std::u16string weil...ja hm. Umlaute? Außerdem sollen später noch andere Schriftzeichen z.B. aus Hebräisch genutzt werden. Das Thema ist wegen der ganzen Kodierung usw. ziemlich komplex und ich hab nicht den kompletten Durchblick.
Naja, ich hab auf StackOverFlow [1] folgendes gefunden:
Code: Alles auswählen
char16_t upper = std::use_facet<std::ctype<char16_t>>(std::locale()).toupper(ch);
Unter GCC kommt zur Laufzeit wegen std::ctype<char16> ein bad_cast Fehler. Ich bin schon fast soweit, irgendwie ICU in mein CMakeFile reinzubasteln oder das Lower / Upper Case Mapping selbst zu schreiben :lol:
[1]
http://stackoverflow.com/questions/6058 ... 16-t-array
Re: [C++] u16string zu lower case
Verfasst: 10.03.2016, 15:31
von Schrompf
Keine Ahnung, ehrlich gesagt. Ich hatte für sowas boost::locale benutzt, was intern auch auf die ICU umbiegt. Aber das Modul wird nicht mehr nennenswert gepflegt. Und da ich irgendwann festgestellt habe, dass ich von den Megabytes an Code und Tabellen eh nur gettext() benutze, hab ich alles wieder rausgeworfen.
Re: [C++] u16string zu lower case
Verfasst: 10.03.2016, 19:20
von Raphael
Dann werde ich wohl tatsächlich manuell eine Map von Groß- zu Kleinbuchstaben und umgekehrt aufbauen, weil alles andere noch mehr Arbeit wäre. Hätte ICU ein CMakeFile wäre alles noch in Ordnung, aber man muss sich selbst die wichtigen cpp's zuammensuchen und die Source hat über 100mb. Alles doof.
Re: [C++] u16string zu lower case
Verfasst: 10.03.2016, 19:35
von Sternmull
Das Problem ist unabhängig vom Encoding, d.h. für utf-8 wäre es auch nicht schwerer/leichter zu lösen. Ohne eine zusätzliche Unicode-Bibliothek wird das mit C++ nicht zu machen sein. Aber davon gibt es ja genug. z.B.
QLocale::toLower() (was aber letzten Endes auch ICU nimmt). Allerdings lässt sich
QT schmerzfrei in CMake verwenden.
Re: [C++] u16string zu lower case
Verfasst: 10.03.2016, 20:27
von Spiele Programmierer
Ich habe mir mal ein paar Unicodetabellen für meine Lib generiert.
Der Code besteht aus nur 2 Headern and 2 Sources. Enthält auch ToLower. Die ToLower Tabelle hat etwa 2kB.
Falls das irgendjemand brauchen kann, habe ich es mal angehängt.
Re: [C++] u16string zu lower case
Verfasst: 10.03.2016, 21:10
von Raphael
Oh cool, schau ich mir an!
Das hier hab ich noch gefunden, soll aber nicht Visual Studio funktionieren :-/
https://github.com/CaptainCrowbar/unicorn-lib
Re: [C++] u16string zu lower case
Verfasst: 13.03.2016, 16:12
von Raphael
Über reddit habe ich jetzt noch etwas in C gefunden, was ich gerade versuche zu integrieren:
https://bitbucket.org/knight666/utf8rewind/overview
Ich scheitere aber an C, glaub ich zumindest. Es kommen keine vernünftigen Buchstaben bei dem Versuch raus, von UTF-8 zu UTF-16 zu konvertieren. Size bei std::string gibt doch die Byteanzahl zurück, oder? Weil wenn ich am Ende bei rOutput statt der size+1 einen festen Werte angebe, kommt ein "ü" schon mal heil durch die Konvertierung...
Code: Alles auswählen
bool convertUTF8ToUTF16(const std::string& rInput, std::u16string& rOutput)
{
// Variables which will be filled
int32_t errors;
size_t size;
// First, determine needed size in new string
size = utf8toutf16(
rInput.c_str(), rInput.size(),
NULL, 0,
&errors);
// Only proceed when no error occured
if (errors == UTF8_ERR_NONE)
{
// Use determined size to reserve space
uint16_t* space = (uint16_t*)malloc(size+1);
space[size] = 0;
// Convert from UTF-8 to UTF-16
utf8toutf16(
rInput.c_str(), rInput.size(),
space, size,
&errors);
// Copy to referenced output string
rOutput = std::u16string((char16_t*)space, size + 1);
// Free space of malloc
free(space);
}
// Return error check
return (errors == UTF8_ERR_NONE);
}
Edit: Habs! std::u16string nimmt in diesem Konstruktor als zweiten Parameter nicht die Anzahl der Bytes sondern die Anzahl der Werte, sprich Dividieren der size durch sizeof(char16_t) löst das Problem. Jetzt noch fröhlich weitere Hilfsfunktionen schreiben...