UTF-8 in C

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
ManuJo
Beiträge: 1
Registriert: Di Mär 30, 2021 9:37 am

UTF-8 in C

Beitrag von ManuJo » Di Mär 30, 2021 9:44 am

Hallo liebe Leute,

ich bin ein bisschen verwirrt, was Unicode, UTF-8 String und ASCII angehen. Ich beschäftige mich mit einer Aufgabe, wo ich bei einer Socketprogrammierung UTF-8 Strings versenden muss. Ich arbeite zurzeit mit char-Pointern und char-Arrays, in denen ich meine Nachrichten abspeichere und diese versende. Jedoch weiss ich nicht, zur welcher Art (Unicode, UTF-8, ASCII) diese chars gehören. Wie kann ich meine char-pointer und -arrays in UTF-8 Strings umwandeln?

Ich kenne mich hier überhaupt nicht aus und wäre sehr dankbar für eure Hilfe!

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8858
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: UTF-8 in C

Beitrag von Xin » Mi Mär 31, 2021 4:34 pm

Hallo erstmal :-)
ManuJo hat geschrieben:
Di Mär 30, 2021 9:44 am
ich bin ein bisschen verwirrt, was Unicode, UTF-8 String und ASCII angehen. Ich beschäftige mich mit einer Aufgabe, wo ich bei einer Socketprogrammierung UTF-8 Strings versenden muss. Ich arbeite zurzeit mit char-Pointern und char-Arrays, in denen ich meine Nachrichten abspeichere und diese versende. Jedoch weiss ich nicht, zur welcher Art (Unicode, UTF-8, ASCII) diese chars gehören.
char-Arrays sind weniger Buchstaben als Bytearrays, wobei ein Byte mindestens 8 Bit hat. Ja, wieviel Bit sollte ein Byte denn sonst haben...? Die Frage zeigt also schon, dass "char" in C nichts mit Unicode zu tun hatte, sondern C standardisierte Computer. Das char war also auch auf Computern verfügbar, die 9 oder 63 Bit pro Byte hatten.

Auf modernen PC - also alles, was in den letzten 40 Jahren produziert wurde, ist ein Byte 8 Bit. Mehr sagt char nicht aus.
ManuJo hat geschrieben:
Di Mär 30, 2021 9:44 am
Wie kann ich meine char-pointer und -arrays in UTF-8 Strings umwandeln?
Das ist alles gar nicht so einfach... Wenn Du ByteArrays in Deinem Deinem Quelltext hast, dann entsprechend die Zeichen 0 bis 127 ASCII. Damit entsprechen Sie auch automatisch UTF8. Bei den Zeichen 128 bis 255 ist es abhängig in welcher Codepage der Quelltext vorliegt. Ein "ä" existiert nicht in jeder Codepage, da ist es dann vielleicht ein graphisches Zeichen wie ein doppelter Vertikalstrich. Es ist also erstmal interessant zu wissen in welcher Codepage der Editor arbeitet. Gehen wir mal vom Standard hier aus: Latin1 oder wie immer fast Standard: Windows-1252.
Also je nach Codepage ergeben die Zeichen 128-255 unterschiedliche Unicode-Zeichen. Nehmen wir Zeichen 128 (0x80) aus der Windows-Codepage: das ist das Eurozeichen €.

Das Eurozeichen hat den Unicode U+20ac. Es muss also das Zeichen 0x20AC, was zwei Byte sind, in Unicode gewandelt werden.

Und jetzt fängt es an lustig zu werden. :-)

Liegt das zu kodierende Zeichen im Bereich von 0x0-7F, ist es einfach das Zeichen. (ASCII). Dabei ist das vordeste Bit 0, also Bitmuster 0000.0000 bis 0111.1111.

Liegt das zu kodierende Zeichen im Bereich von 0x80-7ff, kodiert man 2 Byte. Das erste Byte hat vorne das Bitmuster 1xxx.xxxx, hier ist also was besonderes. Je mehr Byte man anhängt, um so mehr 1-Bits werden im ersten Byte gesetzt, gefolgt von einem Nullbit. Das Zeichen ä ist 0xE4 bzw. UTF+00E4. Das ist größer als 7F, kleiner als 0x7ff: Wir brauchen zwei Byte.

Code: Alles auswählen

1.10.x.xxxx 10.xx.xxxx
1 für Mehrbyte-Zeichen, 10 für 1 Byte Extra, 0 für keine weiteren Bytes extra. Dann 5 Bit Daten, gefolgt vom 2. Byte: 10 für "Ich bin ein Anhängsel" und wieder 6 Bit Daten.

Gucken wir uns E4 als Bitmuster an: 1110.0100, das sind 8 Bit Daten, die da reinkopiert werden müssen. Wir nehmen die 6 Bit von rechts in das Anhängsel und die zwei Bit vorne in das vordere UTF-Byte:

Code: Alles auswählen

1.10.x.xx11 10.10.0100
Die x füllen wir mit 0 auf:

Code: Alles auswählen

1.10.0.0011 10.10.0100
und haben so das Binärmuster: 1100.0011 1010.0100. Das entspricht hexadezimal C3A4, was erfreulicherweise auch der UTF-8 für das kleine ä entspricht. :-)

Beim ä wäre auch andere Kombinationen möglich, wie a (U+0061) - ◌̈ (U+0308), also ein normales a malen und dann erklären, dass da zwei Punkte drüber gehören.

Zurück zum Eurozeichen: U+20ac. Das ist größer als 0x7FF - zwischen 0x800 und 0xFFFF brauchen wir 3 Byte. Also erstes Byte so kodieren, dass zwei Byte folgen:

Code: Alles auswählen

1.110.xxxx 10xx.xxxx 10xx.xxxx
Wir haben also 4+6+6 Bit Nutzdaten, also 16 Bit. Kodieren wollen wir 0x20AC, das sieht in 16 Bit so aus:
0010.0000 1010.1100.
Das Unterteilen wir jetzt passend in drei Blöcke mit 4, 6 und 6 Bit:
0010.000010.101100
und die Blöcke packen wir in die Datenregion der 3 UTF Bits:

Code: Alles auswählen

1.110.0010 10.000010 10.101100
Das ergibt drei Zeichen: 0xE282AC, die in Deinem String dann als UTF

Code: Alles auswählen

char Preistext="Das kostet 5 \xE2\x82\xAC.";
geschrieben werden müssten.

Und ich teste das tatsächlich erst jetzt: Euro-Zeichen als UTF
Nicht verrechnet. :-)

Wenn Du also feststehende Strings hast, kannst Du besondere Zeichen wie hier beschrieben umrechnen und fest mit exadezimalen Werten eingeben, die Du Dir beispielsweise mit der von mir verlinkten Seite raussuchen kannst.

Wenn Du bestehende ASCII-Strings hast, musst Du wissen, in welcher Codepage sie geschrieben wurden und dann entsprechend auf die Unicode-Zeichen ummappen und dann wie oben beschrieben in UTF-8-Bytes einbetten. Das ist frimelig, aber jetzt auch kein Hexenwerk.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Antworten