Hallo zusammen, ich ärgere mich gerade über die mangelnde Darstellung von Umlauten und Sonderzeichen auf meinem Mikrocontrollerprojekt. Darstellung/Schriftart sind ein anderes Thema - hier angesprochen: Beitrag "Grafik-LCD: Schriftarten mit Umlauten/Sonderzeichen" - jetzt geht es mir um die konkrete Umsetzung zwischen den Zeichenketten im Flash und der Darstellung auf dem Display. Bislang habe ich eine eigene Codepage-Funktion verwendet, die von putc() aufgerufen wurde. Für alles zwischen 'A' 'Z' wurde einfach der entsprechende Offset für das Array mit den Zeichensatzdaten addiert. Zeichen darüber (Umlaute, 'ß', 'µ' etc.) wurde mit einer länglichen switch-case-Orgie der entsprechende Array-Eintrag oder der Eintrag des Ersatzzeichens (Rechteck) zugeordnet. Für die Textstrings selbst habe ich darauf geachtet, daß meine Quelltextdateien im WINDOWS-1252-Format gespeichert wurden. Mit dem GCC unter Windows hat das ganz gut geklappt, daß man Texte einfach im Klartext speichern konnte. Da ich das Thema demnächst wieder neu angehen muß, will ich auch den Codepage-Mechanismus noch einmal überdenken. Was mir an meiner Lösung nicht gefallen hat: Habe ich den Quelltext in einer/für eine Linux-Umgebung gebaut, funktionierte die Darstellung der Sonderzeichen auf dem "virtuellen Display" nicht mehr. Komplett von char auf wchar umstellen ist vermutlich nicht sinnvoll auf einem kleinen Mikrocontroller. Also bietet sind entweder UTF-8 oder der Verbleib auf Codepage 1252 an. Lange Rede kurzer Sinn: Wenn ich das quadratische Rad mal wieder neu erfinden muß, interessiert es mich, wie es andere machen. Viele Grüße W.T.
Für Sonderzeichen, die ich selbst erfinde (Notenschlüssel, Lautsprecherchen, Klinkenstecker, Glöckchen usw.) nutze ich den Bereich der ASCII Steuerzeichen von 0x01 bis 0x1F (bis auf CR und LF). Wenn ich ä,ö oder ü im Zeichensatz brauche, schmeisse ich meistens die geschweiften Klammern und den | raus - als Grossbuchstaben habe ich die aber nie benötigt, also nur als Kleinbuchstaben.
Walter T. schrieb: > Lange Rede kurzer Sinn: Wenn ich das quadratische Rad mal wieder neu > erfinden muß, interessiert es mich, wie es andere machen. Du kannst dem Compiler mitteilen, welche Codierung für den Quelltext verwendet wird, und welche Codierung für die Ausgaben verwendet werden soll. Das geschieht mit den Optionen -finput-charset= für den Quelltext und -fexec-charset= für die Ausgabecodierung.
Hallo zusammen, danke für die sehr hilfreichen Antworten! Rufus Τ. F. schrieb: > Das geschieht mit den Optionen > > -finput-charset= > > für den Quelltext > > und > > -fexec-charset= Danke für die Information. Irgendwann hatte ich das auch mal gefunden und wieder vergessen. Das würde sowohl eine Migration von CP-1252 auf UTF-8 erleichtern, als auch problemlos den Status quo auch unter Linux nutzbar lassen (wahrscheinlich wird nur die Input-Codepage falsch interpretiert). Sehr schön. Matthias S. schrieb: > Für Sonderzeichen, die ich selbst erfinde (Notenschlüssel, > Lautsprecherchen, Klinkenstecker, Glöckchen usw.) Auch interessant. Ich nutze für solche Sachen frei positionierbare Piktogramme, da ich da sowieso keine Zeilenausrichtung, Vorschub, verschiedene Größen etc. benötige. Walter T. schrieb: > Bislang habe ich eine eigene Codepage-Funktion verwendet, die von putc() > aufgerufen wurde. Für alles zwischen 'A' 'Z' wurde einfach der > entsprechende Offset für das Array mit den Zeichensatzdaten addiert. > Zeichen darüber (Umlaute, 'ß', 'µ' etc.) wurde mit einer länglichen > switch-case-Orgie der entsprechende Array-Eintrag oder der Eintrag des > Ersatzzeichens (Rechteck) zugeordnet. Wie sieht es damit aus? Gibt es bessere Implementierungsmöglichkeiten für schwach gefüllte Tabellen als switch-case-Reihen? (Irgendwie fühle ich mich immer etwas merkwürdig, wenn ich etwas, was eigentlich Daten sind, als Funktion implementiere.)
Walter T. schrieb: > Wie sieht es damit aus? Gibt es bessere Implementierungsmöglichkeiten > für schwach gefüllte Tabellen als switch-case-Reihen? Naja, wenn 256 oder 128 Bytes Speicher nicht weh tun, kannst Du das als simple Tabelle anlegen. Zeichen rein - Zeichen raus. Für nicht codierte Zeichen wird ein Defaultzeichen verwendet. 256 Byte-Tabellen sind am simpelsten, bei 128 Zeichen kommt vor den Tabellenzugriff noch eine Prüfung, ob Bit 7 gesetzt ist, und nur dann der Tabellenzugriff.
1 | const char chartable[256] = |
2 | {
|
3 | 0x00, |
4 | 0x01, |
5 | 0x02, |
6 | ...
|
7 | 0xFF
|
8 | };
|
9 | |
10 | |
11 | get_char_for_display(char c) |
12 | {
|
13 | return (chartable[c]); |
14 | }
|
oder
1 | const char chartable[128] = |
2 | {
|
3 | 0x00, // Zeichen für 0x80 |
4 | 0x01, |
5 | 0x02, |
6 | ...
|
7 | 0x7F // Zeichen für 0xFF |
8 | };
|
9 | |
10 | |
11 | get_char_for_display(char c) |
12 | {
|
13 | if (c & 0x80) |
14 | return (chartable[c & 0x7f]); |
15 | return (c); |
16 | }
|
Man müsste das halt mal mit der Codegröße Deines realen switch-case-Beispiels vergleichen.
Rufus Τ. F. schrieb: > Naja, wenn 256 oder 128 Bytes Speicher nicht weh tun, kannst Du das als > simple Tabelle anlegen. Stimmt **facepalm**. Die ganze Codepage-Tabelle ist ja nicht größer als ein einziges, popeliges 32x32-Pixel-Pikrogramm (solange ich nicht auf UTF wechsele). Manchmal braucht man eine Diskussion, um auf das Offensichtliche zu stoßen.
Rufus Τ. F. schrieb: > Du kannst dem Compiler mitteilen, welche Codierung für den Quelltext > verwendet wird Das gilt dann aber leider für alle inkludierten Dateien auch, und da die System-Header vermutlich alle ASCII sind bekommt man Probleme, wenn man z.B. UTF-16 einstellt. Über die Prefixe der String-Literale hat man etwas mehr Flexibilität, aber die 8-Bit-Codepages kann man darüber leider nicht auswählen: http://en.cppreference.com/w/cpp/language/string_literal
Matthias S. schrieb: > Für Sonderzeichen, die ich selbst erfinde (Notenschlüssel, > Lautsprecherchen, Klinkenstecker, Glöckchen usw.) nutze ich den Bereich > der ASCII Steuerzeichen von 0x01 bis 0x1F (bis auf CR und LF). > Wenn ich ä,ö oder ü im Zeichensatz brauche, schmeisse ich meistens die > geschweiften Klammern und den | raus - als Grossbuchstaben habe ich die > aber nie benötigt, also nur als Kleinbuchstaben. Das ist dann uebrigens ISO 646 -- fuer die Grossbuchstaben wird [\] verwendet, die Tilde fuer Eszett.
Niklas G. schrieb: > Das gilt dann aber leider für alle inkludierten Dateien auch, und da die > System-Header vermutlich alle ASCII sind bekommt man Probleme, wenn man > z.B. UTF-16 einstellt. Warum sollte man ausgerechnet UTF-16 verwenden? UTF-8 sollte doch genügen, und ist verbreiteter Standard.
Rufus Τ. F. schrieb: > UTF-8 sollte doch > genügen, und ist verbreiteter Standard. Sag das den Windows-Programmierern ;-) Aber du hast schon Recht, bei den ASCII-kompatiblen Encodings wie UTF-8 sollte es unproblematisch sein. UTF-8 ist ja sowieso die Standardeinstellung. Man sollte nur im Hinterkopf behalten dass -finput-charset nicht alles kann...
Niklas G. schrieb: > Sag das den Windows-Programmierern ;-) Selbst Visual Studio verwendet UTF-8 als Defaultcodierung für Quelltext. Die 16-Bit-Unicode-Variante ist weniger für Quelltext, als für Gebrauch der schon sehr lange existierenden Win32-API erforderlich. UTF-8 hat halt einen großen Nachteil: Funktionen wie strlen werden ziemlich aufwendig.
Rufus Τ. F. schrieb: > UTF-8 hat halt einen großen Nachteil: Funktionen wie strlen werden > ziemlich aufwendig. Das sind sie aber auch bei UTF-16, denn Unicode passt schon lange nicht mehr in nur 16 Bits hinein. Für moderne neue Emoticons braucht es 32 Bits...
Kommt drauf an was man will... Wenn man nur die Anzahl an belegten Bytes braucht, reicht strlen(). Wenn man die Anzahl an einzelnen Zeichen ("grapheme clusters") braucht ists unabhängig von der Kodierung sehr kompliziert, da mehrere Codepoints zusammen ein "Zeichen" ergeben können, und es auch noch verschiedene Varianten gibt, diese darzustellen. Siehe: https://www.unicode.org/faq/char_combmark.html#7 Dafür benutzt man am Besten eine Bibliothek wie libicu: http://site.icu-project.org/
Jim M. schrieb: > Rufus Τ. F. schrieb: >> UTF-8 hat halt einen großen Nachteil: Funktionen wie strlen werden >> ziemlich aufwendig. > > Das sind sie aber auch bei UTF-16, denn Unicode passt schon lange nicht > mehr in nur 16 Bits hinein. Deswegen ist das, was bei Windows Verwendung findet, eben auch nicht UTF-16, sondern UCS-16. Sprich: die Zeichenbreite ist konstant 16 Bits. Klar: Etliche Unicode-Zeichen lassen sich damit nicht codieren. Aber wenn man nicht gerade unbedingt die neuesten Hirn-Blähungen der Emoticon-Szene benötigt oder was mit historischen Sprachen zu tun hat, dann reicht der Zeichenvorrat locker aus. Alle lebenden Schriftsprachen können damit dargestellt werden und dazu noch ein Unmasse von mehr oder weniger nützlichen weiteren Zeichen. Außerdem darf man nicht vergessen: die Zeichenketten sind nur der weit kleinere Teil des Datenmülls im Speicher. Der Hauptverbrauch entsteht durch die Font-Glyphen, die zu seiner Darstellung nötig sind. Was nützt eine Codierung, die 4T Zeichen repräsentieren kann, wie etwa UTF-8 oder UTF-16, wenn die allermeisten dieser Zeichen dann doch wieder nur als "default char" dargestellt werden können, weil halt der verwendete Font sie nicht enthält... So gesehen, ist das UCS-16 von Windows ein sehr, sehr guter Kompromiss, um den Resourcenverbrauch sowohl bezüglich des Speichers als auch bezüglich der Rechenzeit im Rahmen zu halten. Und übrigens wird dieser Kompromiss längst nicht nur von Windows verwendet...
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.