UTF-8 'durchschleifen'/konvertieren
-
Hast du meinen Post denn nicht gelesen?
Es bringt dir absolut nichts, Unicode mit fester „Zeichenlänge“ zu speichern, da ein Unicode-Codepunkt eben nicht zwingend ein Zeichen geschweige denn ein Glyph ist. Der einzige „Vorteil“ ist, dass du dir keine ungültigen Zeichen durch unvorsichtiges abschneiden oder einfügen basteln kannst, aber das kann mit gewissenhafter Programmierung auch gut verhindert werden.
find etc. funktionieren natürlich auch mit UTF-8-Strings.
-
.filmor schrieb:
Der einzige „Vorteil“ ist, dass du dir keine ungültigen Zeichen durch unvorsichtiges abschneiden oder einfügen basteln kannst, aber das kann mit gewissenhafter Programmierung auch gut verhindert werden.
find etc. funktionieren natürlich auch mit UTF-8-Strings.Dann zeigt mal wie du ein funktionierendes lenght, find oder replace auf nem utf-8 string in nem std::string machst.
-
Length geht per Definition nicht anständig und ist auch wenig sinnvoll. find und replace tun's, wenn ich nach UTF-8 suche und mit UTF-8 ersetze. Wo ist das Problem?
-
.filmor schrieb:
Hast du meinen Post denn nicht gelesen?
Es bringt dir absolut nichts, Unicode mit fester „Zeichenlänge“ zu speichern, da ein Unicode-Codepunkt eben nicht zwingend ein Zeichen geschweige denn ein Glyph ist. Der einzige „Vorteil“ ist, dass du dir keine ungültigen Zeichen durch unvorsichtiges abschneiden oder einfügen basteln kannst, aber das kann mit gewissenhafter Programmierung auch gut verhindert werden.
find etc. funktionieren natürlich auch mit UTF-8-Strings.Ich habe jetzt nochmal nachgeschaut. Unter Windows wird intern wohl UCS-2 als 16 Bit Unicode verwendet. Ich Zitiere mal aus der wikipedia, und hebe die Stelle hervor:
UCS-2 (2-byte Universal Character Set) is an obsolete character encoding which is a predecessor to UTF-16. The UCS-2 encoding form is nearly identical to that of UTF-16, except that it does not support surrogate pairs and therefore can only encode characters in the BMP range U+0000 through U+FFFF. As a consequence it is a fixed-length encoding that always encodes characters into a single 16-bit value. As with UTF-16, there are three related encoding schemes (UCS-2, UCS-2BE, UCS-2LE) that map characters to a specific byte sequence.
Jetzt sag mir bitte was ich falsch verstehe. Ich weiß selbst das UTF-X nicht zwangsweise 1 Buchstabe für eine Basiseinheit X hat, aber zumindestens unter bestimmten Betriebssystemen wird für die Verwendung in der UI etc. auf ein System mit einer fixen Breite umgewandelt. Und wenn ich weiterhin Windows als beispiel verwende, dient hier dieses System auch als Basis für die Strings unter .Net.
Mag sein das ich manches falsch verstanden habe, aber sollte ich mich hier irren, so wäre das falschen Informationen über eben diese Formate zuzuschreiben (ich bin beileibe kein Unicodeexperte, habe mich damit aber auch schon länger Beschäftigt und recherchiert).
Und wenn man in einen System arbeitet wo eine Fixe Länge definiert ist, so sag mir warum die Algorithmen nicht funktionieren sollten.
cu André
-
@asc es geht wohl eher darum, dass es nichts bringt, auf wchar_t kodierungen umzuschwenken(die normal 16Bit lang sind), um dann wieder daten zu verliereren(eben die surrogate pairs).
Mein Vorschlag:
std::basic_string<unsigned int,char_traits<unsigned int> > utf32string.
mit:
template <typename octet_iterator, typename u32bit_iterator> u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result);
aus der gelinkten utf8 lib. Das reicht zumindest, solange du nicht mit streams rumhantieren musst. ab dann wird es eh, egal welche kodierung, richtig ekelhaft. Wenn man bedenkt, dass es standardlibs ohne wchar_t implementierung gibt, wird einem ganz schwarz vor augen, mit einem für C++ völlig fremden Zeichensatz zu arbeiten.
-
Mir geht's vor allem um solche Späße. Die machen alle Vorteile bis auf die beinahe garantierte Validität von UTF-32 oder ähnlichem zunichte.
-
.filmor schrieb:
Length geht per Definition nicht anständig und ist auch wenig sinnvoll. find und replace tun's, wenn ich nach UTF-8 suche und mit UTF-8 ersetze. Wo ist das Problem?
Das ist ja ein extremer Aufwand, dann musst du jede Benutzereingabe, Konstante usw. zuerst nach UTF-8 Konvertieren. So gut wie keine Funktion gibt dir UTF-8 zurück, wenn du jetzt einmal zu konvertieren vergisst, dann hast du so nen dummen Fehler nach dem du ewig suchst.
-
.filmor schrieb:
Mir geht's vor allem um solche Späße. Die machen alle Vorteile bis auf die beinahe garantierte Validität von UTF-32 oder ähnlichem zunichte.
Autsch. ok, da braucht man nen eigenen char type. langsam dämemrts mir, warum utf support als standard proposal abgelehnt wurde.
-
sososo schrieb:
.filmor schrieb:
Length geht per Definition nicht anständig und ist auch wenig sinnvoll. find und replace tun's, wenn ich nach UTF-8 suche und mit UTF-8 ersetze. Wo ist das Problem?
Das ist ja ein extremer Aufwand, dann musst du jede Benutzereingabe, Konstante usw. zuerst nach UTF-8 Konvertieren. So gut wie keine Funktion gibt dir UTF-8 zurück, wenn du jetzt einmal zu konvertieren vergisst, dann hast du so nen dummen Fehler nach dem du ewig suchst.
Das ist im wesentlichen auch ein Punkt von mir.
Ich weiß das Unicode weit mehr als UCS-2 ist (Sorry, ich beschränke mich bei meinen Beispiel jetzt erstmal auf das System das ich kenne: Windows), aber nichts desto trotz wird man es ohnehin schwer haben in Bereichen die vom System nativ nicht abgedeckt werden sinnvoll zu arbeiten. Und innerhalb eines Systemes ist es durchaus ein möglicher 90% Weg, sich auf einen Kompromiss zu beschränken.
Ich hätte nichts dagegen wenn ich einen (möglichst portablen) Weg finde um mit UTF8 bis UTF-32 wirklich sinnvoll arbeiten zu können (Von dem Dateihandling bis zur UI), nur ist die sinnvolle Beschreibung wie man damit in Programmiersprachen gut umgeht entweder kaum vorhanden, oder es sind einfach zuviel Mülltreffer beim googlen um damit ernsthaft zu arbeiten. Sorry, ich erwarte das man nicht erst den ganzen Unicode-Standard durchackern muss um mit Unicode arbeiten zu können. Mich interessiert auch bei einem Container nicht die konkrete Umsetzung (auch wenn ich vielleicht den ein oder anderen schon selbst implementiert habe).
Das Problem liegt ja nicht nur bei C++ mit seiner mangelnden Unterstützung, sondern es gibt genügend andere Sprachen die wenn sie Unicode anbieten intern auch mit einem mehr oder weniger weitreichenden Kompromiss arbeiten.
cu André
-
Wo liegt denn das Problem? Die Kombinations„zeichen“ werden ja erst relevant, wenn man den Text tatsächlich rendern will und da muss man eh sukzessive Vorgehen (also ist's egal, ob man wahlfreien Zugriff hat), entsprechendes gilt für die meisten Parser. Normalisierungsroutinen sind nicht so schwer zu schreiben und abgesehen davon auch gut verfügbar. Mir fällt wirklich kein Fall ein, in dem ich Random-Access /und/ Unicode bräuchte …
otze schrieb:
.filmor schrieb:
Mir geht's vor allem um solche Späße. Die machen alle Vorteile bis auf die beinahe garantierte Validität von UTF-32 oder ähnlichem zunichte.
Autsch. ok, da braucht man nen eigenen char type.
Eben nicht. UTF-8 in char ftw!
@asc: UCS-2 hilft dir da mal überhaupt nicht weiter. Die Combining Characters gibt's da auch. Mir geht's nicht um UTF-16, das ist eh total verkorkst, sondern um beliebige Fixed-Byte-Encodings für Unicode, also UTF-32 oder die UCS-2-Untermenge von UTF-16. Es nutzt einfach nichts.
-
Ja genial!
Jetzt folge ich nicht mehr mit Abstand, sondern ich renne ziellos durch die dunklen Gassen dieser was-auch-immer.....
Entschuldigt bitte, wenn ich jetzt immer noch nicht weiß, was ich machen kann und wenn ich nicht mehr viel verstanden habe.
Vielleicht könnt Ihr Euch gemeinsam auf Antworten zu 1-5 (siehe erste Seite) einigen, zumindest partiell?!
Im Prinzip möchte ich natürlich viele Sonderzeichen abdecken, aber wenigstens die dt. Umlaute und die Standards der verbreiteteren Sprachen wäre sinnig....hilfe!
-
IMHO solltest du für alles std::string mit UTF-8 benutzen (dokumentieren nicht vergessen ;)) und nur für den allerletzten Schritt die Umwandlung zu der geforderten Kodierung durchführen.
Aber die ist doch bei LPCTSTR gar nicht eindeutig, oder?
Bei dem Schritt könnte jedenfalls diese codecvt-Facette helfen, Beispiel ist auch dabei. Wenn du Boost nicht verwenden möchtest kannst du einfach die utf8_codecvt_facet.hpp und die entsprechende .cpp-Datei nehmen, die benötigen AFAIK keine anderen Boost-Bibliotheken außer Boost.Config und davon kannst du den Code einfach rauswerfen (ist nur Präprozessorkram).
-
.filmor schrieb:
IMHO solltest du für alles std::string mit UTF-8 benutzen (dokumentieren nicht vergessen ;)) und nur für den allerletzten Schritt die Umwandlung zu der geforderten Kodierung durchführen.
Aber die ist doch bei LPCTSTR gar nicht eindeutig, oder?
Bei dem Schritt könnte jedenfalls diese codecvt-Facette helfen, Beispiel ist auch dabei. Wenn du Boost nicht verwenden möchtest kannst du einfach die utf8_codecvt_facet.hpp und die entsprechende .cpp-Datei nehmen, die benötigen AFAIK keine anderen Boost-Bibliotheken außer Boost.Config und davon kannst du den Code einfach rauswerfen (ist nur Präprozessorkram).Aber wozu dieser ganze Aufwand, dass man überall an UTF-8 denken muss, wenn es am Schluss doch LPCTSTR also 16 bit Unicode wird?
Für wen soll den das Programm sein?
-
.filmor schrieb:
Bei dem Schritt könnte jedenfalls diese codecvt-Facette helfen, Beispiel ist auch dabei.
Das ist kein encoding nach wchar_t, sondern einfach nach utf32:
utf8_codecvt_facet is a specialization of std::codecvt specifically designed to handle the case of translating between UTF-8 and UCS-4.
-
Ja, aber UTF-32 ist bis 0xFFFF kompatibel zu UTF-16.
-
und danach willst du unkontrolliert zeichensalat produzieren?
-
Also ersteinmal thx an .filmor für den Versuch.
Dann Dank an alle anderen, die sich beteiligen, danach eine Antwort:
Ich sammle INet-Info und gebe sie auf's Display der Logitech G15 aus, auf den im Logitech-SDK mitgelieferten Wrapper.Bitte nicht falsch verstehen, ich bin dankbar für jeden Beitrag (auch wenn ihr mich regelmäßig abhängt), aber vielleicht können diejenigen, die '.filmor's Versuch 'zerpflückt' haben, einen eigenen Vorschlag machen.
Wie würdet ihr denn vorgehen?Der Vorteil für mich ist, dass ich mit den Vorschläge mehr anfangen kann, als mit Eurer Diskussion danach
Zwischenfrage: Habe ich denn überhaupt eine Chance, den UTF-8-Krams gleich zu konvertieren, um danach mit dem normalen std::string zu arbeiten?
Oder analoges dazu, wenn ich alle meine jetzigen std::string's in std::wstring's ändere?
Und noch eine Frage:
Wo genau ist denn jetzt bei mir das Problem, wenn die Sonderzeichen nicht (korrekt) am Display ankommen? Darin, dass ich std::string benutzte, das ich den utf-8 codierten std::string manipuliere (gibt's das so? - mache ich auch nicht immer, geht trotzdem nicht) oder darin, dass die Übergabe ans Display einfach mit c_str() gemacht wird (gleich muss ich mir wohl etwas anhören...)?
Vielleicht kann man auch da ansetzen.
-
SammyRukka schrieb:
Bitte nicht falsch verstehen, ich bin dankbar für jeden Beitrag (auch wenn ihr mich regelmäßig abhängt), aber vielleicht können diejenigen, die '.filmor's Versuch 'zerpflückt' haben, einen eigenen Vorschlag machen.
Wie würdet ihr denn vorgehen?Da ich von den Standardfällen ausgehe würde ich tatsächlich die Gefahr eines gewissen Informationsverlustes in Kauf nehmen und intern auf eine 16 bzw. 32 bit-Repräsentation (std::wstring) konvertieren. Da sich aber .filmor scheinbar so gut damit auskennt kann er ja mal sagen wie man mit UTF-8 sinnvoll in einem C++ Programm arbeitet (Vom Einlesen bis hin zur UI-Darstellung). Und das an besten noch mit sinnvollen Quellen im Internet oder in Buchform, nach denen ich schon seit Jahren vergeblich suche (Und es kann nicht sein das man sich eine eigene UTF-8 Bibliothek schreiben muss).
Vielleicht ist ja das hier (ICU) etwas für dich.
cu André
-
Schau dir mal an, wie die einzelnen Codierungen (ASCII, UTF-8 UNICODE) aufgebaut sind. Schau nach, was dieses Logitech G15 Display bzw. das Famework dazu kann. Dann kannst du dir ganz leicht überlegen, ob es sinnvoll ist bis zum Ende UTF-8 durchzuschleifen (mit allem was du dabei bedenken musst) oder ob es besser ist gleich beim Einlesen zu konvertieren.
-
@vorschlag:
SammyRukka schrieb:
Zwischenfrage: Habe ich denn überhaupt eine Chance, den UTF-8-Krams gleich zu konvertieren, um danach mit dem normalen std::string zu arbeiten?
Oder analoges dazu, wenn ich alle meine jetzigen std::string's in std::wstring's ändere?Bei der Diskussion habe ich den Faden verloren, deshalb ja die Frage. Meinetwegen kann ich gleich konvertieren. Ich hänge nicht so am UTF. Es soll am Ende halt nur normal aussehen, damit meine ich wenigstens die Umlaute.