Ich arbeite an einem Terminal-basierten Programm, das Unicode-Unterstützung hat. Es gibt bestimmte Fälle, in denen ich feststellen muss, wie viele Terminalspalten eine Zeichenfolge verbraucht, bevor ich sie drucke. Leider sind einige Zeichen 2 Spalten breit (chinesisch, etc.), aber ich fand this answer, die eine gute Möglichkeit zur Erkennung von Zeichen mit voller Breite anzeigt, indem Sie u_getIntPropertyValue() von der ICU-Bibliothek aufrufen.Wie erkennt man Unicode-String-Breite im Terminal?
Jetzt versuche ich, die Zeichen meiner UTF8 Zeichenfolge zu analysieren und sie an diese Funktion zu übergeben. Das Problem, das ich jetzt habe, ist, dass u_getIntPropertyValue() einen UTF-32-Codepunkt erwartet.
Was ist der beste Weg, um dies aus einer utf8-Saite zu erhalten? Ich versuche das gerade mit boost :: locale (anderswo in meinem Programm), aber ich habe Probleme, eine saubere Konvertierung zu bekommen. Meine UTF32-Strings, die von boost :: locale stammen, sind mit einem zero-width character versehen, um die Byte-Reihenfolge anzuzeigen. Natürlich kann ich die ersten vier Bytes der Saite einfach überspringen, aber gibt es einen saubereren Weg, dies zu tun?
Hier ist meine aktuelle hässliche Lösung:
inline size_t utf8PrintableSize(const std::string &str, std::locale loc)
{
namespace ba = boost::locale::boundary;
ba::ssegment_index map(ba::character, str.begin(), str.end(), loc);
size_t widthCount = 0;
for (ba::ssegment_index::iterator it = map.begin(); it != map.end(); ++it)
{
++widthCount;
std::string utf32Char = boost::locale::conv::from_utf(it->str(), std::string("utf-32"));
UChar32 utf32Codepoint = 0;
memcpy(&utf32Codepoint, utf32Char.c_str()+4, sizeof(UChar32));
int width = u_getIntPropertyValue(utf32Codepoint, UCHAR_EAST_ASIAN_WIDTH);
if ((width == U_EA_FULLWIDTH) || (width == U_EA_WIDE))
{
++widthCount;
}
}
return widthCount;
}
Wenn Sie bereits ICU verwenden, warum es nicht zu UTF-8-to-UTF32 Umwandlung verwenden für? –
Ich bin nicht mit der Intensivstation vertraut. Ich habe versucht, boost :: locale zu verwenden, um mich vor dem größten Teil der Komplexität zu isolieren. Gibt es eine einfache Möglichkeit, diesen utf32-Code direkt von der ICU zu bekommen? – KyleL
Ich kenne mich auch nicht aus, aber ich weiß, dass es alles hat, was jemand von einer Unicode-Bibliothek wollte. Verbringen Sie etwas Zeit mit Google und Sie werden es finden. –