Hallo zusammen, ich stehe vor dem Problem z.B. das Sonderzeichen "ě" welches an Adresse 0x011B liegt auf einem Grapfik Display darstellen zu müssen. Die Firmware existiert bereits und läuft für Deutsch und Englisch. Soll nun also mit Sprachen und den entsprechenden Zeichen erweitert werden. Bisher sind nur die unteren 255 Zeichen gepixelt und die ganze Adressierung ist nur 1 Byte groß. Das muss ich also eigentlich als erstes umbauen, um auch die nächsten Zeichen die oberhalb von 0xFF liegen anzeigen/adressieren zu können. Hier fangen die Probleme schon an. Derzeit sind meine Texte via "Beispiel" im Flash abgelegt. Sobald nun ein Zeichen mit zwei Byte Adressierung dazwischen kommt, habe ich ein Problem. Wie soll ich diesen Text im Speicher ablegen. Bei ASCII Zeichen kümmert sich hierum ja der Compiler. Das nächste Problem wären dann die Funktionen mit denen die Strings verarbeitet werden. Diese Funktionieren dann ja auch nichtmehr, da diese von 1-Byte pro Zeichen ausgehen. Ich habe hier schon recherchiert und multibyte String Funktionen gefunden. Ich möchte aber trotzdem fragen wie ihr so ein Problem löst. Adressiert ihr die Zeichen einfach in den noch freien Stellen der unteren 256 Adressen? und schaltet diese dann quasie händisch um, sodass die Adressierung im 1 Byte Raum bleiben kann? Suche hier noch nach der einfachsten Möglichkeit... Danke schonmal! Gruß, Bean
D. S. schrieb: > Bisher sind nur die unteren 255 Zeichen gepixelt und die ganze > Adressierung ist nur 1 Byte groß. [...] > Bei ASCII Zeichen kümmert sich hierum ja der Compiler. ASCII definiert nur 128 Zeichen (0...127). Ich nehme jetzt mal an, dass es sich um C handelt: Erstmal ist nicht klar, ob char signed oder unsigned ist, also ob die restlichen Zeichen die Werte 128...255 oder -128...-1 haben. Bei kleinen uCs mache ich das normalerweise so, dass ich diesen Wertebereich für die nötigen Sonderzeichen nutze. Beispiel:
1 | #define DISPLAY_UE "\xAA" /* hier den richtigen Wert eintragen */ |
2 | const char * const MeinText = "K" DISPLAY_UE "he machen M" DISPLAY_UE "he"; |
Etwas mühsam, funktioniert aber. Du schreibst aber, dass du bereits 255 Zeichen definiert hast. Da sehe ich keinen Umweg um Multibyte Zeichen herum. uchar.h definiert wide string characters und wchar.h liefert die nötigen Funktionen dazu. Habe ich selbst noch nie benutzt, daher kann ich dir dabei keine Tipps geben. http://www.cplusplus.com/reference/cuchar/ http://www.cplusplus.com/reference/cwchar/
:
Bearbeitet durch User
Hallo Be Stucki, danke für dein Feedback! Ja, es handelt sich um C. Der Wertebereich wäre positiv. Und Du hast natürlich recht, bisher ist nur der ASCII Zeichensatz allerdings von 20h bis FFh gepixelt. Also unsigned char. Ok, das was Du beschreibst, wäre die andere Möglichkeit die ich sehe. Also die Sonderzeichen von z.B. 0x11B an die Adresse 0x80 zu pixeln. Das würde derzeit funktioniere, da hier noch keine Zeichen hinterlegt sind. Würde aber ein "um Mappen" der Zeichen zur Folge haben. Ich müsste dann in meinem String schreiben "\x80". Könnte also nichtmehr direkt das Zeichen "eingeben". Ab Adresse 0x80 sind bis 0xFF sind schon einige Sonderzeichen enthalten. Aber eben nicht alle, die ich brauche. :-( Gruß, Bean
Um Unicode- bzw. UTF-8-Zeichen zu verarbeiten, kannst du Wide-Characters und -Strings aus wchar.h verwenden und ggf. die Ausgabecodierung mit setlocale aus locale.h festlegen. Da du aber die Codierung für internationale Zeichen wohl nur innerhalb deines Programms brauchst (ausgegeben werden ja nur die Pixel auf dem Grafikdisplay), ist es einfacher und speichereffizienter, eine 8-Bit-Codierung wie ISO 8859-15 zu verwenden, sofern sie alle von dir benötigten Zeichen enthält. Wenn du deinen Editor oder C-Compiler entsprechend einstellst, kannst du die Sonderzeichen in Stringliteralen auch direkt (ohne \x) in den Quellcode eintippen. Ich sehe gerade, dass ISO 8859-15 nicht geht, das dort das "ě" fehlt. Wieviele unterschiedliche Zeichen brauchst du denn insgesamt? Sind es mehr als 255?
Hallo Yalu, :-) Genau das ist die Frage die mir derzeit auch keiner beantworten kann. Geplant sind 14 Sprachen. Welche Sonderzeichen ich hier alle brauche, habe ich noch nicht gezählt. Irgendwo geistern aber auch noch Wünsche nach Asiatischen Schriftzeichen herum... Dann ist aus meiner Sicht eh Ende mit dem 1-Byte Adressraum. Kennt ihr eine gute Seite, wo man sich die verschiedenen Zeichensätze anschauen kann? Gruß, Bean
Ich habe gerade mal verglichen. Derzeit gepixelt ist auf unserem Gerät der ISO/IEC 8859-15 Zeichensatz...
D. S. schrieb: > ich stehe vor dem Problem z.B. das Sonderzeichen "ě" welches an Adresse > 0x011B liegt Und schon falsch. Zeichen "liegen" nicht an "Adressen". Zeichensätze definieren eine 1:1 Abbildung zwischen Zeichen und Zeichencodes. Z.B. hat dein oben genanntes Zeichen in Unicode den Code U+011B. Das gleiche Zeichen existiert aber auch in ISO Latin-2 mit dem Code 0xEC. Auch in Windows-1250 leigt dieses Zeichen auf 0xEC. http://www.fileformat.info/info/unicode/char/011b/index.htm http://www.fileformat.info/info/unicode/char/011b/charset_support.htm https://de.wikipedia.org/wiki/ISO_8859-2 > Die Firmware existiert bereits und läuft für Deutsch und Englisch. Soll > nun also mit Sprachen und den entsprechenden Zeichen erweitert werden. Dann werdet euch als allererstes klar, welchen Zeichenvorrat ihr unterstützen wollt. Die Unicode BMP (basic multilingual plane aka die Unicode Codepoints U+0000 bis U+FFFF) ist zwar sicherlich am universellsten, aber alleine der Zeichensatz für ~65000 Zeichen braucht wahrscheinlich mehr Platz im ROM als eure ganze Anwendung. Wenn man nur eine Teilmenge der Zeichen braucht, dann bieten sich die ISO Latin-X Zeichensätze an, die nur 256 Zeichen enthalten. > Derzeit sind meine Texte via "Beispiel" im Flash abgelegt. Sobald > nun ein Zeichen mit zwei Byte Adressierung dazwischen kommt, habe ich > ein Problem. Wie soll ich diesen Text im Speicher ablegen. > Bei ASCII Zeichen kümmert sich hierum ja der Compiler. UTF-8 ist extra dafür entwickelt worden, um einen gleitenden Übergang von 8-Bit Zeichencodierungen zu Unicode zu erleichtern. Latin-X verhält sich in jeder Hinsicht gleich wie ASCII. > Das nächste Problem wären dann die Funktionen mit denen die Strings > verarbeitet werden. Diese Funktionieren dann ja auch nichtmehr, da diese > von 1-Byte pro Zeichen ausgehen. Ich habe hier schon recherchiert und > multibyte String Funktionen gefunden. > Ich möchte aber trotzdem fragen wie ihr so ein Problem löst. Wenn das Zielsystem genug Resourcen hat, würde ich heute auf Unicode und UTF-8 Codierung setzen. Den Zeichensatz würde man dann aber "sparse" implementieren. Z.B. die ersten 256 Zeichen (entspricht Latin-1) komplett und von den Codepoints U+0100 bis U+FFFF nur den Teil, der wirklich gebraucht wird. Latin-X oder Windows-XXXX ist eine gute Sparlösung, hat ja auch in Form der "Codepages" bei WinDOS jahrzehntelang gut funktioniert. Ob es paßt, hängt von der Anwendung ab.
Axel S. schrieb: > Wenn das Zielsystem genug Resourcen hat, würde ich heute auf Unicode und > UTF-8 Codierung setzen. Den Zeichensatz würde man dann aber "sparse" > implementieren. Z.B. die ersten 256 Zeichen (entspricht Latin-1) > komplett und von den Codepoints U+0100 bis U+FFFF nur den Teil, der > wirklich gebraucht wird. Würde ich so machen. Die Alternative wäre, für verschiedene Sprachen verschiedene Codepages zu verwenden. So könnten vielleicht die 8bit beibehalten werden. Das ganze mutiert aber zu unwartbarem Murks.
:
Bearbeitet durch User
Es gibt noch eine Sparlösung, die mit 8 Bit pro Zeichen auskommt. Die kann man sich z.B. bei den HD44780 Displays anschauen. Diese Displays implementieren alle ASCII Zeichen auf den Positionen 0x20 bis 0x7F. In der oberen Hälfte von 0x80 bis 0xFF findet man dann z.B. Latin-15 oder irgendein schräges Komglomerat aus asiatischen Zeichen und europäischen Sonderzeichen. Darüber hinaus sind die Zeichen mit den Codes 0x00 bis 0x1F ja Steuerzeichen, die separat ausgewertet werden und selber nicht auf dem Bildschirm dargestellt werden. Diese Positionen im Zeichensatz kann man auch noch für darstellbare Zeichen benutzen. Der Nachteil an allen diesen Sparlösungen ist, daß nur für wenige davon die Strings in einem normalen Editor geschrieben (und angezeigt) werden können. Wenn man viel mit Strings hantieren muß oder sie z.b. aus dem PC übertragen will, braucht man dann Konvertierungsfunktionen.
D. S. schrieb: > Wie soll ich diesen Text im Speicher ablegen. Als UTF-8, das ist die standardisierte 8-bit Codierung für Unicode. Und netterweise für ASCII, also die amerikanischen Zeichen, sogar identisch. Du musst also beim Speichern und weiterleiten der Daten gar nichts anders machen. Das Display bekommt dann eventuell mehrere Bytes für nur 1 darzustellendes Zeichen. Dazu muss es erstens die Bytes zusammenfassen damit die Codezahl des Zeichens rauskommen. Falls du Positionen auf Grund der Stringlänge berechnen willst, musst du mbslen für UTF8 verwenden, die liefert die Anzahl der Zeichen.
Hallo, also auf jeden Fall haben wir Nordische Sprachen (z.B. Dänisch, Finnisch) und Osteuropäische (z.B. Tschechisch, Ungarisch). Womit ich nach meinem jetzigen Verständniss mindestens zwei Zeichensätze bräuchte (Latin-1 und Latin-2). In allen anderen genannten Zeichensätzen (UTF-8) sind hierfür nicht alle Zeichen enthalten. Sehe ich das richtig!? Das "ě" wie es in der tschechischen Sprache gebraucht wird finde ich in dieser Tabelle: http://www.utf8-chartable.de/ jedenfalls nicht. Gruß und danke! Bean
D. S. schrieb: > Das "ě" wie es in der tschechischen Sprache gebraucht wird finde ich in > dieser Tabelle: > http://www.utf8-chartable.de/ > jedenfalls nicht. Aber hier: http://www.utf8-chartable.de/unicode-utf8-table.pl?start=256 UTF-8 hat weitaus mehr als 256 Zeichen. Schau mal ober auf der Seite bei "go to other block".
:
Bearbeitet durch User
D. S. schrieb: > Kennt ihr eine gute Seite, wo man sich die verschiedenen Zeichensätze > anschauen kann? Hier ist eine Liste der gebräuchlichsten Kodierungen: https://en.wikipedia.org/wiki/Character_encoding#Common_character_encodings Auf den jeweils verlinkten Seiten findest du für die meisten davon auch eine Zeichentabelle. Aber so viel wird dir das nicht nützen, solange du nicht genau weißt, welche Zeichen du tatsächlich brauchst. Und am Ende wird die Entscheidung vielleicht doch auf UTF-8, -16 oder -32 hinauslaufen, weil damit praktisch alle Zeichen darstellbar sind, die du jemals brauchen wirst.
Ok, da mein "ě" bei UTF-8 im nächsten Block liegt, sehe ich das als UTF-16 an. Da ich hier ja noch das nächste Byte brauche. Vielleicht liegt hier aber auch mein Denkfehler. Reicht es aus, wenn ich meinen Compiler und meine IDE auf UTF-8 stelle? Erkennt "adressiert" er das Zeichen "ě" dann richtig mit 0x011B!? Dann müsste ich meinen Zeichensatz aber trotzdem auf 2 Byte umbauen, da ich ja die 0x01 aus dem HighByte auch irgendwie verarbeiten muss. Sorry für meinen dumme Fragerei, aber ich sehe die praktische Lösung (wie komme ich zu C-Sourcecode der mir das "ě" anzeigt) noch nicht... Gruß, Bean
D. S. schrieb: > ... auf jeden Fall haben wir Nordische Sprachen (z.B. Dänisch, > Finnisch) und Osteuropäische (z.B. Tschechisch, Ungarisch). > Womit ich nach meinem jetzigen Verständniss mindestens zwei Zeichensätze > bräuchte (Latin-1 und Latin-2). Schau auch mal Windows-1250 bzw. 1252 an > In allen anderen genannten Zeichensätzen (UTF-8) sind hierfür nicht alle > Zeichen enthalten. Sehe ich das richtig!? Das siehst du falsch. UTF-8 ist eine Transportcodierung für Unicode. Da gibt es jedes Zeichen. > Das "ě" wie es in der tschechischen Sprache gebraucht wird finde ich in > dieser Tabelle: http://www.utf8-chartable.de/ jedenfalls nicht. Die Tabelle ist ja auch nur für die ersten 256 Zeichen von Unicode. Aka Latin-1. Einen besseren Link hatte ich dir oben ja schon gegeben: http://www.fileformat.info/info/unicode/char/011b/charset_support.htm das listet alle Zeichensätze bzw. Codepages auf, die das gewünschte Zeichen enthalten. Etwas allgemeiner: dein Zeichen bei http://www.fileformat.info/info/unicode/char/search.htm suchen. Auf der Seite für das Zeichen unter "Encodings" auf "More" klicken.
D. S. schrieb: > Ok, da mein "ě" bei UTF-8 im nächsten Block liegt, sehe ich das als > UTF-16 an. Wie du das ansiehst ist ziemlich egal, UTF-16 ist ein 16Bit (2Byte) Format, UTF-8 ist eine Codierung variabler Länge, die für die üblichen westlichen Zeichen für die meisten Zeichen mit nur einem Byte auskommt.
Dazu kommt noch folgendes: Du kannst zwar mit den verschiedenen ISO8859 Zeichensätze verschiedene Sprachen darstellen, in dem du den entsprechenden Zeichensatz bei dir auswählst. Du kannst aber nicht auf einer Seite mehrere Sprachen mischen. Das geht in der PC Welt und auf Webseiten prinzipiell nicht. Deswegen hat man Unicode eingeführt. Damit kannst du alle, wirklich alle Zeichen der Welt auf einmal darstellen. Passt natürlich nicht mehr in ein Byte, so dass die "exotischen" Zeichen bei UTF-8 zwei oder auch mehr Bytes verwenden. Ich habe ein ähnliches Problem mit einem 16x2 Textdisplay, welches nicht einmal alle Umlaute kann. Da der Text, der dort u.a. angezeigt wird vom User in der App bestimmt wird, müssen alle nicht-ASCII Zeichen umgewandelt werden. Sieht zwar nicht schön aus, bewahrt aber davor, dass das Display nicht darstellbare Bytes bzw. strlen falsche Länge bekommt. Für dich wäre es eine Möglichkeit, dir eine Konvertierungsfunktion zu schreiben, die den Zeichensatz deines Editors in dein eigenes Mapping umschreibt. In dieses Mapping machst du ab 128 alle Zeichen rein, die du brauchst.
>UTF-8 ist eine Codierung variabler Länge, die für die üblichen >westlichen Zeichen für die meisten Zeichen mit nur einem Byte auskommt. Genau, allerdings nicht für mein "ě". Da bin ich nämlich bei 0x011B. Ich glaube das mit den verschiedenen Zeichensätzen habe ich jetzt verinnerlicht. >Für dich wäre es eine Möglichkeit, dir eine Konvertierungsfunktion zu >schreiben, die den Zeichensatz deines Editors in dein eigenes Mapping >umschreibt. In dieses Mapping machst du ab 128 alle Zeichen rein, die du >brauchst. Geht schon ziemlich in die Richtung die ich auch als Lösung im Kopf habe. Gruß, Bean
D. S. schrieb: > Ok, da mein "ě" bei UTF-8 im nächsten Block liegt, sehe ich das als > UTF-16 an. Nein UTF-8 hat keine "Blöcke". Unicode hat Blöcke. Ein Zeichencode aus dem Unicode-Universum heißt Codepoint und wird U+xxxx geschrieben, wobei xxxx eine Hexadezimalzahl ist. Es gibt keine Längenbegrenzung für diese Hexadezimalzahl. In den ersten Versionen von Unicode glaubte man noch, 4 Stellen (U+0000 bis U+FFFF) würden reichen. Mittlerweile sind aber deutlich mehr als 65536 Zeichen (U+000000 bis U+10FFFF) in Unicode standardisiert so daß 2 Byte pro Zeichen nicht mehr reichen, um alle Zeichen aus Unicode darzustellen. UTF-8 ist eine Codierung, die Unicode-Zeichen in einen Strom von Bytes codiert und dabei die Eigenschaft behält, daß 0x00 in keinem Zeichen vorkommt, folglich weiterhin als Endekennzeichen verwendet werden kann. UTF-16 ist das gleiche für einen Strom von 16-Bit Worten. Sowohl in UTF-8 als auch in UTF-16 kann ein einzelnes Zeichen in einer Variablen Anzahl von Bytes (UTF-8: 1..5 Bytes) bzw. Worten (UTF-16: 1 oder 2 Worte) codiert werden.
:
Bearbeitet durch User
D. S. schrieb: > Ok, da mein "ě" bei UTF-8 im nächsten Block liegt, sehe ich das > als > UTF-16 an. Da ich hier ja noch das nächste Byte brauche. > Vielleicht liegt hier aber auch mein Denkfehler. Ja, du machst immer noch nicht die Trennung zwischen der internen Speicherung (Kodierung) eines Wertes und dem Wert selber. Die UTF-x Kodierungs-Formate (in voller Schönheit UTF = Universal Character Set Transformation Format) beschreiben wie ein Wert im Speicher abgelegt wird oder übertragen wird. Also das Bitmuster. Zum Beispiel ist UTF-8 dabei für kleine Werte kompakt (1 Byte für Werte 0 - 0x7f), kann aber alle Werte bis 0x1fffff kodieren. Für 0x1ffff braucht es allerdings 4 Bytes (eine unkodierte Speicherung von 0x1ffff würde nur 3 Bytes belegen und einige MSBs wären dabei noch unbenutzt). UTF-8 ist für große Werte also weniger effizient und hat den Nachteil, dass es ein Format mit variabler Länge ist, je nach Wert werden mal mehr mal weniger Bytes zur Speicherung verwendet. Die Werte die man mit UTF-8 oder genauso mit UTF-16 speichern kann entsprechen den selben Zeichen im Universal Character Set (UCT). Die Werte werden Code Points genannt, und sind bei UTF-8 eben nicht 1:1 die Bytes im Speicher. Jedem Code Point ist ein Glyphe zugeordnet. Der Glyphe ist die sichtbare Repräsentation eines Zeichens. > Reicht es aus, wenn ich meinen Compiler und meine IDE auf UTF-8 stelle? Nein, dann kannst du deinen Source-Code in UTF-8 speichern und der Compiler würde bei einem String Literal mit ě die entsprechende UTF-8 Bytefolge einfügen. > Erkennt "adressiert" er das Zeichen "ě" dann richtig mit 0x011B!? Nein, warum sollte er? Die UTF-8 Kodierung für den Code-Point 0x011b sind zwei Bytes 0xc4 0x9b. Die würdest du in deinem Sourcecode-File, bzw. in deinem Compiler-Output sehen. > Dann müsste ich meinen Zeichensatz aber trotzdem auf 2 Byte umbauen, da > ich ja die 0x01 aus dem HighByte auch irgendwie verarbeiten muss. Ehm ... Du müsstest die Abbildung von Code Points auf Glyph-Daten so umbauen, dass auch die Daten für Zeichen mit Code Points > 255 gefunden werden. Da es offensichtlich keinen Sinn macht dafür ein Array (Lookup-Table) mit zum Beispiel 2097152 Einträgen zu verwenden (Wertebereich von UTF-8), wirst du dafür eine andere Technik benötigen. Zum Beispiel Binäres Suchen in einer sortierten Liste von unterstützten Code Points oder eine Hashtable (aka Map). Natürlich kann man bei UTF-8 ein bisschen optimieren und für die ersten 128 Code Points eine kleine Lookup-Table verwenden. Für die weiteren dann die sortierte Liste oder Map. > Sorry für meinen dumme Fragerei, aber ich sehe die praktische Lösung > (wie komme ich zu C-Sourcecode der mir das "ě" anzeigt) noch nicht... Speicher-Kodierung auswählen, zum Beispiel UTF-8. Dann ist der Weg vom Inhalt im Speicher:
1 | UTF-x dekodieren -> Code Point -> Glyph Daten -> Display |
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.