Troll19: Typkonvertierung in C bzw. Perl

0 43

Typkonvertierung in C bzw. Perl

  1. 0
    1. 0
      1. 0
        1. 0
          1. 0
  2. 0
    1. 0
  3. 0
  4. 0
    1. 0
      1. 0
      2. 0
        1. 0
          1. 0
          2. 0

            Über den Umgang mit Binaries in C und in Perl

            1. 0
              1. 0
                1. 0
                  1. 0
                    1. 0
                      1. 0
                        1. 2
                          1. 0
                            1. 0

                              Soso.

                              1. 0
                                1. 1
                                  1. 0
                                    1. 0
                                    2. 0
                                2. 0
                                3. 1
                2. 0
                  1. 0
          3. 0
            1. 0
              1. 0
                1. 0
                  1. 0
                    1. 0
                      1. 0
                        1. 0
                  2. 1

Hallo,

ich möchte den Hex-Cpde eines Zeichens in druckbarer Form ausgeben.

Beispiel: Die Variable ZEICHEN enthält den Buchstaben "ü".

In C: char ZEICHEN[]="ü";

In Perl: my $ZEICHEN="ü";

Die Variable enthält dann den Wert 0xfc.

Diesen Wert möchte ich nun so konvertieren, dass in der Variablen ZEICHEN2 der String "fc" (0x66 + 0x63) steht. Mit einer einfachen Konvertierung ist das natürlich nicht zu machen. Gibt es eine Möglichkeit, das linke und das rechte Halbbyte vom "ü" jeweils getrennt in einen Integerwert zu konvertieren? Dann könnte ich ein Array "0123456789abcdef" definieren und mit dem Interwert darauf zugreifen.

Kann mir jemand helfen?

Vielen Dank Troll19

  1. Hallo Troll19,

    Das hat zwar mit deiner Frage nichts zu tun, aber schau dir mal die Formatierungshilfe unter https://wiki.selfhtml.org/wiki/SELFHTML:Forum/Formatierung_der_Beiträge an, erreichbar mit dem roten Fragezeichen über dem Texteingabefeld. Insbesondere Zeilenumbrüche werden dich interessieren. Vielleicht möchtest du deinen Beitrag noch einmal in leserlicher Form absenden?

    Bis demnächst
    Matthias

    --
    Pantoffeltierchen haben keine Hobbys.
    1. Hallo, tut mir leid, dass der Text offenbar verunglückt ist. Mit dem roten Fragezeichen kann ich leider nicht viel anfangen. Ich bin blind und arbeite mit einem Screenreader, der mir den Bildschirminhalt vorliest bzw. zeilenweise auf einer mechanischen Braillezeile darstellt. Da bekommt man von der Formatierung, wie sie sich auf dem Bildschirm darstellt, nicht so viel mit. Da muss ich wohl warten, bis jemand im Haus ist, der mir dabei helfen kann.

      Gruß Troll19

      1. Hallo Troll19,

        Ich bin blind und arbeite mit einem Screenreader

        Ah, ok. Bitte setze einfach zwei Zeilenumbrüche, wenn du einen neuen Absatz beginnen möchtest. Ich repariere deinen Beitrag entsprechend deiner Intention.

        Bis demnächst
        Matthias

        --
        Pantoffeltierchen haben keine Hobbys.
        1. Hallo

          Ich repariere deinen Beitrag entsprechend deiner Intention.

          Hab' ich gerade gemacht.

          Tschö, Auge

          --
          Eine Kerze stand [auf dem Abort] bereit, und der Almanach des vergangenen Jahres hing an einer Schnur. Die Herausgeber kannten ihre Leser und druckten den Almanach auf weiches, dünnes Papier.
          Kleine freie Männer von Terry Pratchett
          1. Vielen Dank euch beiden.

            Gruß Troll19

  2. Hallo Troll19,

    für C hätte ich zwei Vorschläge. Einmal eine "handgemachte" Konvertierung, einmal mit Hilfe von sprintf.

    Der Code beginnt mit Deklarationen der beiden Konvertierfunktionen, dumpString und dumpString2. Dann kommt die main-Funktion als Testtreiber, danach die handgemachte Variante. Sie besteht aus der Hilfsfunktion toHex und der Konvertierfunktion dumpString. Danach kommt die Variante mit sprintf, sie heißt dumpString2.

    In der handgemachten Variante muss man die Null-Terminierung der Ausgabe selbst machen. Bei sprintf erledigt das die Library.

    C-Code mit einer Braille Zeile zu verstehen ist eine besondere Leistung. Meinen Respekt!

    #include <stdio.h>
    
    int dumpString(char* buffer, int bufSize, char* s);
    int dumpString2(char* buffer, int bufSize, char* s);
    
    int main()
    {
        char outputBuffer[100] = "***********123456789";
        printf("Hello World\n");
        dumpString2(outputBuffer, 11, "Hello World");
        printf("%s\n", outputBuffer);
    
        return 0;
    }
    
    char toHex(char c)
    {
        return c + (c < 10 ? '0' : 'W');
    }
    int dumpString(char* buffer, int bufSize, char* s)
    {
        int p;
        for (p=0; *s && p<bufSize-2; p+=2)
        {
            buffer[p] = toHex((*s & 0xf0)>>4);
            buffer[p+1] = toHex(*s++ & 0x0f);
        }
        buffer[p] = '\0';
        return p>>1;
    }
    
    int dumpString2(char* buffer, int bufSize, char* s)
    {
        int p;
        for (p=0; *s && p<bufSize-2; p+=2)
            sprintf(buffer+p, "%02x", *s++);
    
        return p>>1;
    }
    

    Rolf

    --
    sumpsi - posui - clusi
    1. Hallo Rolf, vielen Dank für die beiden Lösungen. Das werde ich mir morgen noch mal auf der Zunge zergehen lassen, um es wirklich zu verstehen. Gruß Troll19.

  3. hi,

      unsigned char *uml = "ü"; // Datei utf-8 gespeichert
      printf("0x%02X 0x%02X", uml[0], uml[1]); // 0xC3 0xBC
    

    fertig 😉

    PS: Beachte das unsigned !

    printf "0x%02X 0x%02X", unpack "CC", "ü";
    

    auch fertig.

    Un nochwas: Halbe Bytes gibt es nicht!

  4. Hallo,

    eine Möglichkeit, das linke und das rechte Halbbyte vom "ü" jeweils getrennt

    Wie auch immer das ü kodiert ist, Halbbytes gibt es nicht. In ISO-8859-01 hat das ü ein Byte mit der Wertigkeit FC. In UTF-8 siehe da, da sind es 2 Bytes.

    Da das Byte die kleinste Speichereinheit ist, in C sind das die Datentypen unsigned char und uint8_t müsstest Du mit Bitoperatoren arbeiten. Mir ist jedoch nicht ganz klar was Du gegeben hast und was Du daraus machen willst.

    Mit Typumwandlungen hat das nichts zu tun.

    MfG

    1. Hallo pl,

      da ein Byte aus 8 Bit besteht, kann man es auch halbieren. Das Ergebnis hat einen Namen: Ein Nibble (oder Nybble). Mit der Architektur der heutigen Computer kann man es nicht direkt adressieren und muss Nibbles über Bitoperationen isolieren, aber deswegen verschwinden sie nicht aus der Welt. Die Intel-Prozessorfamilie hat sogar auf Assembler-Ebene ein eigenes Flag für Nibble-Overflow, aus der Zeit, wo man Zahlen noch BCD-codiert speicherte (in meinen alten COBOL Zeiten habe ich das als COMPUTATIONAL-3 oder PACKED Format kennengelernt).

      Um ein Byte als zweistelligen Hexwert darzustellen, übersetzt man seine beiden Nibbles in ihre hexadezimale Darstellung. Siehe dazu oben meine toHex Funktion und die Bitoperationen in dumpString, wo genau das passiert.

      Rolf

      --
      sumpsi - posui - clusi
      1. hi @Rolf B

        ahja, das Nibble. Lange nicht gehört, danke !

        Indes sind Bitoperatoren ja auch keine Hexerei:

        printf "%X %X" , 0xFC >> 4  & 0xF, 0xFC & 0xF; 
        # Ergebnis: F C
        # und in C funktioniert das genauso
        

        Also einmal 4 Bits nach rechts schieben und die Maske 00001111 anlegen ergibt die Zahl aus der linken Hälfte. Rechte Hälfe analog nur muss da nicht geschoben werden.

        MfG

      2. hin again,

        wenn das Zeichen gegeben ist (hier als Binary direkt aus der C-Datei), siehts dann so aus:

            unsigned char *uml = "ü"; // Datei in ISO-8859-1 gespeichert
            printf("%X %X\n", uml[0] >> 4 & 0xF, uml[0] & 0xF);
        

        und in Perl kriegst Du die Oktettenwertigkeit mit unpack("C", "ü") aus der Binary. Beachte daß die Dateien mit dem Code in der richtigen Zeichenkodierung gespeichert sind!

        MfG

        1. Hallo,

          Vielen Dank an euch alle. Meine Frage ist voll beantwortet. Es freut mich, dass ich das Problem auch mit Perl erledigen kann. Mit dem UNPACK habe ich schon experimentiert. Aber ich habe offenbar nicht die richtigen Parameter gefunden.

          Die Bezeichnung Typkonvertierung habe ich aus folgendem Grund verwendet:

          In einem Buch im Internet habe ich die automatische Typkonvertierung in C gefunden. Demnach sollte man folgendes schreiben:

          char v1 = 'a';

          int v2 = v1;

          Bis 0x7f funktioniert das auch so weit. Man bekommt zwar nicht den Hex-Code, aber immerhin den Integerwert. Über 0x7f hört der Spaß dann auf, weil das höchstwertige Bit als Vorzeichen interpretiert wird. Das Beispiel im Buch war natürlich so gewählt, dass es kein Problem gab. Auch das Schlüsselwort unsigned hilft nicht wirklich weiter. Aber hier kam ja nun unsigned char ins Spiel. Davon hatte ich noch nichts gehört. In meinem Beitrag hatte ich aber schon geschrieben, dass es mit einer Typkonvertierung wohl nicht getan ist. Insofern war der Begriff wohl nicht zutreffend.

          Nun noch ein paar Worte zur Erklärung:

          Ich komme eigentlich aus der Großrechnerwelt und habe über mehrere Jahrzehnte Software entwickelt. Ein bisschen in Cobol und ganz überwiegend Assembler. Da gab es die Halbbytes (Zonenteil und Ziffernteil genannt). Die Großrechner sind bei uns Geschichte. Hauptamtlich bin ich auch kein Entwickler mehr. Jetzt programmiere ich nur noch, um mir hier und dort die Arbeit zu erleichtern. Dazu habe ich mir im Selbststudium awk, Perl und ein bisschen C angeeignet. C aber nur ungern.

          Gruß Troll19

          1. Hi,

            nun die Halbbytes gibt es ja doch: Nibbles. Ist mir nur gestern nicht eingefallen 😉

            Zu Perl's pack/unpack, es gibt da eine Eselsbrücke:

            pack() packt zusammen und erzeugt die Bytes aus Integerwerten. pack "C", 65 erzeugt also ein Byte was aussieht wie ein A. Mehrere Bytes heißt mehrere Platzhalter in der Schablone, so erzeugt pack "CCCC", 56,66,67,68 die Binary ABCD. unpack() ist die Umkehrung, Zahlen links, Binary rechts.

            In C gibt es mehrere Möglichkeiten. fprintf(stdout,"%c%c%c%c", 65,66,67,68) würde dasselbe machen wie pack obenstehend. Es gänge aber auch so in C:

                unsigned char a[4] = {65,66,67,68};
                fwrite(a, sizeof a, 1, stdout);
            

            womit diese 4 Bytes gleich am Stück in das Handle geschrieben werden was natürlich auch eine Datei sein kann. Interessant wirds mit 4 Bytes, wenn Du aus der Großrechnerwelt kommt, die Packschblone V steht für Vax. In C ist das uint32_t und das ist ein Little Endian.

            Und schließlich steht die Packschablone "V" für 4 Bytes die man in Perl mit "C4" bekommt.

            MfG

          2. problematische Seite

            Ein kleiner Artikel Der richtige Umgang mit Binaries in C und in Perl

            Passend zum Thema 😉

            1. problematische Seite

              Hallo pl,

              nicht passend zum Thema, sondern schön aus dem Thema zusammengeschrieben. Auf deiner Seite veröffentlicht als dein eigenständiges Werk. Habe grad keinen Teer da, sonst würde ich Dich mit noch ein paar Federn mehr schmücken.

              Wenn Du uns hier schon zum Lernen nutzt, dann gibt auch Credit wem Credit gebührt. Nicht zwingend einzelnen, aber der Community von selfhtml.

              Rolf

              --
              sumpsi - posui - clusi
              1. problematische Seite

                hi @Rolf B

                Hab noch einige Fehler gefunden und korrigiert. Es ist übrigens nicht mein erster Artikel über meine C-Leidenschaft und Perlartikel schreibe ich seit Jahrzehnten.

                Was C so richtig interessant macht ist der Fakt, daß Binaries in C als Bytesequenzen in den Hauptspeicher gelegt werden. Also wie in Dateien.

                Im Übrigen habe ich auch einige Artikel für SELFHTML geschrieben!

                MfG

                1. problematische Seite

                  Hallo pl,

                  Im Übrigen habe ich auch einige Artikel für SELFHTML geschrieben!

                  Aha. Nenn mir zwei.

                  Bis demnächst
                  Matthias

                  --
                  Pantoffeltierchen haben keine Hobbys.
                  1. problematische Seite

                    Im Übrigen habe ich auch einige Artikel für SELFHTML geschrieben!

                    Aha. Nenn mir zwei.

                    Aber gerne!!! Perl: Formulareingaben parsen mit der cgi-lib.pl und Perl: Datenbankanbindung mit ODBC. Und C: CGI mit C entwickeln.

                    Pionierarbeit in Sachen Webentwicklung!!!

                    1. und wo sind die zu finden?

                      1. Das musst Du schon die Experten von SELFHTML fragen!

                        1. Hallo pl,

                          Das musst Du schon die Experten von SELFHTML fragen!

                          Als ehemaliger Entwickler nur folgendes: Die haben wir auf deinen eigenen Wunsch damals gelöscht.

                          Gruß
                          Patrick

                          1. Das musst Du schon die Experten von SELFHTML fragen!

                            Als ehemaliger Entwickler nur folgendes: Die haben wir auf deinen eigenen Wunsch damals gelöscht.

                            Das ist eine Lüge!

                            Die Aufforderung zum Löschen kam nicht von mir sondern von einem Dritten der die Exclusivrechte für diese Artikel erworben hatte.

                            MfG

                            1. Das musst Du schon die Experten von SELFHTML fragen!

                              Als ehemaliger Entwickler nur folgendes: Die haben wir auf deinen eigenen Wunsch damals gelöscht.

                              Das ist eine Lüge!

                              Die Aufforderung zum Löschen kam nicht von mir sondern von einem Dritten der die Exclusivrechte für diese Artikel erworben hatte.

                              Dann war es doch Dein Herzenswunsch, diesem "Dritten" die Exklusivrechte zu verkaufen. Das daraus dann das Löschungsverlangen gegenüber SelfHTML folgte war, wie schon aus dem "Exklusiv" folgt, derart zwingend, dass das Löschungsverlangen durchaus - ohne zu lügen - als Dein eigener Wunsch bezeichnet werden darf.

                              Und da habe ich noch nicht einmal darüber nachgedacht, welcher "Dritte" warum wohl "Exklusivrechte" an einem Artikel, der auf SelfHTML bereits veröffentlicht ist, überhaupt erwirbt. Das kommt mir ziemlich "spanisch" vor, juristisch ist der Übergang von Exklusivrechten(sic!) vom Autor an einem auf Betreiben des Autors zuvor bereits an Dritter Stelle veröffentlichten(sic!) Artikel zudem "mindestens fragwürdig". Man könnte auch sagen "juristisch unmöglich" - und um das zu wissen muss man nicht Jura studiert haben, das ist einfache Logik.

                              Meine Meinung zu diesem Vorgang lautet auf: "Soso." Da das nicht jeder versteht gibt es davon eine Langfassung: "Ich denk mir meinen Teil und merke mir das sehr genau!"

                              1. Denken kannst was Du willst, aber wenn Du Dich öffentlich dazu äußern möchtest, dann bleibe bitte bei den Fakten! Das solltest doch gerade Du am Besten wissen!

                                Fak ist, daß ich mehrere Artikel für SELFHTML geschrieben habe. Was daraus geworden ist, steht hier überhaupt nicht zur Debatte!

                                MfG

                                1. Fak ist, daß ich mehrere Artikel für SELFHTML geschrieben habe. Was daraus geworden ist, steht hier überhaupt nicht zur Debatte!

                                  Soso. Also ich denke, Du hast selbst darüber debattiert, was aus den Artikeln geworden ist:

                                  Patrick C.: Als ehemaliger Entwickler nur folgendes: Die haben wir auf deinen eigenen Wunsch damals gelöscht.

                                  PL: Das ist eine Lüge!

                                  PL: Die Aufforderung zum Löschen kam nicht von mir sondern von einem Dritten der die Exclusivrechte für diese Artikel erworben hatte.

                                  Und wie die Dinge liegen habe ich über das, was Du hier selbst eingebracht und also höchstselbst öffentlich zur Debatte gestellt hast, im Rahmen der hierdurch von Dir selbst angestoßenen Debatte öffentlich nachgedacht.

                                  Ich werde jetzt - trotz der soeben erfolgte Widerlegung Deiner Behauptung - nicht behaupten, dass Du lügst, denn die Lüge setzt eine Absicht und "besseres Wissen" voraus. Allerdings sind die denkbaren Alternativen nicht wirklich schmeichelhaft.

                                  1. Nochmal: Halte Dich bitte zurück mit Deinen Äußerungen und Behauptungen die juristisch nicht haltbar sind!

                                    Wir beide wissen doch, was bürgerliches Recht ist. Schau mal, ich habe auch schon zu DDR Zeiten Artikel für Fachzeitschriften geschrieben. Da war die Rechtslage eben so, daß ich einen Artikel an mehrere Verlage verkaufen durfte!

                                    Gleichermaßen galt dieses Recht auch für den Verkauf von selbstangefertigten Fotografien, auch davon habe ich Gebrauch gemacht.

                                    MfG

                                    1. PL: Die Aufforderung zum Löschen kam nicht von mir sondern von einem Dritten der die Exclusivrechte für diese Artikel erworben hatte.

                                      UC: Und da habe ich noch nicht einmal darüber nachgedacht, welcher "Dritte" warum wohl "Exklusivrechte" an einem Artikel, der auf SelfHTML bereits veröffentlicht ist, überhaupt erwirbt. Das kommt mir ziemlich "spanisch" vor, juristisch ist der Übergang von Exklusivrechten(sic!) vom Autor an einem auf Betreiben des Autors zuvor bereits an Dritter Stelle veröffentlichten(sic!) Artikel zudem "mindestens fragwürdig". Man könnte auch sagen "juristisch unmöglich" - und um das zu wissen muss man nicht Jura studiert haben, das ist einfache Logik.

                                      PL: Wir beide wissen doch, was bürgerliches Recht ist. Schau mal, ich habe auch schon zu DDR Zeiten Artikel für Fachzeitschriften geschrieben. Da war die Rechtslage eben so, daß ich einen Artikel an mehrere Verlage verkaufen durfte!

                                      Du hast geschrieben, der "Dritte" hätte "Exclusivrechte" erworben. Du hast also - wenn Du behaupten willst, hier von vergleichbaren Sachverhalten zu berichten - mehreren Verlagen exklusive Rechte an ein und demselben Artikel verkauft? Auch in der DDR war Betrug - hier womöglich sogar mit der Beschwerung "Straftat gegen das sozialistische Eigentum und die Volkswirtschaft" - strafbar. Und es ist Betrug, wenn man einem Dritten, Viertem oder sogar Fünftem, gegen Geld "exklusive Rechte" an einem Werk abtritt - weil man die selbst - schon nach dem Verkauf an einen Zweiten - gar nicht mehr hat.

                                      Ergo bezweifle ich, dass Du hier über vergleichbare Vorgänge behauptest. Und mir fällt auf, wie sorgfältig Du Zitate vermeidest. Die würden ja nicht dazu passen. Und ich frage mich, ob Du Dritte oder nur Dich selbst täuschen willst.

                                      Allerdings bin ich für eine solche Täuschung nicht der ideale Kandidat.

                                    2. Hallo pl,

                                      und noch was, auch wenn ich weiß, dass die Artikel aus einem anderen Grund gelöscht wurden: Allein mit gesundem Menschenverstand kann man stark bezweifeln, dass sich jemand ernsthaft im fraglichen Zeitraum die Rechte an einem Artikel über cgi-lib.pl gesichert hat. Diese Bibliothek war da schon lange veraltet.

                                      Gruß
                                      Patrick

                                2. Hallo pl,

                                  Fak ist, daß ich mehrere Artikel für SELFHTML geschrieben habe. Was daraus geworden ist, steht hier überhaupt nicht zur Debatte!

                                  Getroffene Hunde bellen.

                                  Bis demnächst
                                  Matthias

                                  --
                                  Pantoffeltierchen haben keine Hobbys.
                                3. Hallo pl,

                                  Denken kannst was Du willst, aber wenn Du Dich öffentlich dazu äußern möchtest, dann bleibe bitte bei den Fakten! Das solltest doch gerade Du am Besten wissen!

                                  Fak ist, daß ich mehrere Artikel für SELFHTML geschrieben habe. Was daraus geworden ist, steht hier überhaupt nicht zur Debatte!

                                  Du hattest in deiner wie immer charmant-liebenswürdigen Art in den Raum gestellt, dass die SELFHTML-Admins und -Redakteure besser wissen, was aus deinen Artikeln geworden ist. Das klingt für mich nach „Ich weiß es leider nicht, wo die hin sind. Die scheinen ohne mein Zutun von den Admins gelöscht worden zu sein.“. Ich habe daraufhin mitgeteilt, dass du derjenige warst, der die Löschung veranlasst hatte.

                                  Im übrigen ist das keine Lüge, ich weiß noch sehr genau, wie wir uns dazu entschlossen hatten, die Artikel auf deinen Wunsch hin zu löschen und dem dann auch Folge geleistet hatten (ich war auch derjenige, der dich von der damaligen Dankesliste entfernt hatte). Ich erinnere mich auch noch an einige der Dinge, die zu der Aktion geführt hatten.

                                  Wenn man archive.org bedienen kann, sieht man auch, wann deine Artikel von SELFHTML aktuell verschwunden sind. Es gibt wahrscheinlich keine Logs mehr vom damaligen SVN, die das beweisen können, aber wenn man einige öffentliche (!) Posts aus dem Forums-Archiv aus dieser Zeit liest, passt das auch zusammen.

                                  Gruß
                                  Patrick

                2. problematische Seite

                  Im Übrigen habe ich auch einige Artikel für SELFHTML geschrieben!

                  Datum und Uhrzeit von einem Zeitserver, Sockets in Perl war einer meiner Artikel für SELFHTML.

                  Hier ist das Teil in C

                  1. problematische Seite

                    Hallo pl,

                    Datum und Uhrzeit von einem Zeitserver, Sockets in Perl war einer meiner Artikel für SELFHTML.

                    Es gibt aber keine Artikel für SELFHTML von dir mehr, weil, das entnehme ich deinen Aussagen, du sie (für dich, nicht für SELFHTML) monetarisiert hast.

                    Bis demnächst
                    Matthias

                    --
                    Pantoffeltierchen haben keine Hobbys.
          3. Moin Troll19,

            In einem Buch im Internet habe ich die automatische Typkonvertierung in C gefunden. Demnach sollte man folgendes schreiben:

            char v1 = 'a';
            
            int v2 = v1;
            

            Achtung: int und char haben unterschiedliche Wertebereiche! Ein char ist 8 Bit/1 Byte groß, ein int üblicherweise 32 Bit/4 Byte. Mit der Zuweisung int v2 = v1; hast du also einen Wert erzeugt, der erst einmal mit drei Bytes der Wertigkeit 0 beginnt; wenn char ASCII-kompatibel ist, ist

            char v1 = 'a';     /* 0x61 */
            
            int v2 = v1; /* 0x00000061 */
            

            Das heißt umgekehrt auch, dass die Rückkonvertierung char v1 = v2; potenziell verlustbehaftet ist, wenn v2 > 0xff.

            Bis 0x7f funktioniert das auch so weit. Man bekommt zwar nicht den Hex-Code, aber immerhin den Integerwert.

            Du kannst jeden Integerwert auch hexadezimal darstellen lassen.

            Über 0x7f hört der Spaß dann auf, weil das höchstwertige Bit als Vorzeichen interpretiert wird.

            Das ist eine Besonderheit von C, da ein char auch ein 8-bittiger Integer wert ist. Wenn du unsigned char verwendest (oder dem Compiler sagst, dass er char als unsigned char kompilieren soll), ist das höchstwertige Bit kein Vorzeichen. Aber im Zeichenkontext spielt das Vorzeichen meiner Erfahrung eh keine Rolle, das heißt, dass z.B. bei Verwendung von ISO-8859-1 folgendes möglich ist:

            signed char umlaut = 'ä';  /* 0xe4 in ISO-8859-1 */
            

            Über 0x7f fängt der Spaß erst richtig an, weil man Zeichenkodierungen berücksichtigen muss 😉

            Viele Grüße
            Robert

            1. hi @Robert B.

              Über 0x7f fängt der Spaß erst richtig an, weil man Zeichenkodierungen berücksichtigen muss 😉

              Wenn Du bei der Bytesemantic bleibst, spielt die Zeichenkodierung überhaupt keine Rolle. Und das ist nicht nur in C so.

                  unsigned char *eurosign = "€";
                  printf("%d Bytes\n", strlen(eurosign)); // 3 Bytes
              
                  uint8_t *n = (uint8_t*)eurosign;
              
                  printf("%X %X %X", n[0], n[1],n[2]); // E2 82 AC
              

              MfG

              1. Moin pl,

                Über 0x7f fängt der Spaß erst richtig an, weil man Zeichenkodierungen berücksichtigen muss 😉

                Wenn Du bei der Bytesemantic bleibst, spielt die Zeichenkodierung überhaupt keine Rolle. Und das ist nicht nur in C so.

                Oh doch! Wie gut, dass du ein Beispiel mitgereicht hast:

                    unsigned char *eurosign = "€";
                    printf("%d Bytes\n", strlen(eurosign)); // 3 Bytes
                
                    uint8_t *n = (uint8_t*)eurosign;
                
                    printf("%X %X %X", n[0], n[1],n[2]); // E2 82 AC
                

                Wenn ich meinen Quellcode in ISO-8859-1 speichere und kompiliere, erhalte ich:

                unsigned char eurosign[] = "€";  /* ← Diese Variante der Stringnotation wird weniger von Compilern angemeckert. */
                printf("%u Bytes\n", strlen(eurosign));  /* 1 Zeichen (2 Bytes: das Zeichen und '\0'). strlen gibt immer einen unsigned Wert zurück, daher das passende Formatflag! */
                
                printf("%x %x\n", eurosign[0], eurosign[1]);  /* a4 0 */
                

                Viele Grüße
                Robert

                1. problematische Seite

                  hi @Robert B.

                  Wenn ich meinen Quellcode in ISO-8859-1 speichere

                  Logisch, dann kriegst Du eine andere Bytesequenz!

                  und kompiliere

                  Auch logisch, wenn man mit Bytesequenzen nicht richtig umgeht, macht das Programm nicht das was es soll oder wird gar nicht erst kompiliert.

                  Ebenfalls falsch:

                  char e = "€"; // Quelldatei UTF-8 kodiert
                  

                  was schon der Kompiler nicht durchgehen lässt. Siehe Artikel

                  MfG

                  1. problematische Seite

                    Hallo pl,

                    Ebenfalls falsch:

                    char e = "€"; // Quelldatei UTF-8 kodiert
                    

                    das ist unabhängig von der Zeichenkodierung falsch: ' umgrenzen in C einen (1) char, " eine Zeichenkette, d.h. in deinem Beispiel passen die Datentypen nicht zueinander. Je nach Zeichenkodierung des Quelltexts funktioniert also

                    char e = '€';
                    

                    Viele Grüße
                    Robert

                    1. problematische Seite

                      hi @Robert B.

                      Je nach Zeichenkodierung des Quelltexts funktioniert also

                      char e = '€';
                      

                      Das funktioniert nur, wenn die Quelldatei in einer Kodierung gespeichert ist in welcher das Zeichen genau ein Byte hat! Sonst meldet der Kompiler einen Fehler

                      warning: multi-character character constant [-Wmultichar]
                      

                      MfG

                      1. problematische Seite

                        Moin pl,

                        Je nach Zeichenkodierung des Quelltexts funktioniert also

                        char e = '€';
                        

                        Das funktioniert nur, wenn die Quelldatei in einer Kodierung gespeichert ist in welcher das Zeichen genau ein Byte hat!

                        Ach was?

                        Sonst meldet der Kompiler einen Fehler

                        warning: multi-character character constant [-Wmultichar]
                        

                        Das ist eine Warnung, kein Fehler. Um mit gcc daraus einen Fehler zu machen, musst du noch -Werror angeben.

                        Microsofts C++-Compiler warnt bei UTF-8 übrigens

                        euro-utf8.c(3): warning C4305: 'initializing': truncation from 'int' to 'const char'

                        Der Beispielcode, jeweils in ISO-8859-15 sowie UTF-8 gespeichert:

                        #include <stdio.h>
                        
                        const char e = '€';  /* Zeile 3 */
                        
                        int main(void) {
                        	printf("%c / %x\n", e, e);
                        
                        	return 0;
                        }
                        

                        Die Ausgaben:

                        Viele Grüße
                        Robert

                        1. problematische Seite

                          So isses! Und was lernen wir daraus? Genau:

                          1. In Dateien gibt es keine Kodierung sondern nur Bytes,
                          2. Dateien sind Bytesequenzen,
                          3. Jede Zeichenkodierung ist ein Serialize-Algorithmus der das Ziel hat, Zeichen auf Bytes abzubilden.

                          Typisierung und Binaries

                          MfG

                  2. problematische Seite

                    Hallo pl,

                    Wenn ich meinen Quellcode in ISO-8859-1 speichere

                    Logisch, dann kriegst Du eine andere Bytesequenz!

                    Ich zitiere dich aus dem Posting direkt davor:

                    Wenn Du bei der Bytesemantic bleibst, spielt die Zeichenkodierung überhaupt keine Rolle.

                    Diese Aussage ist offensichtlich falsch.

                    char e = "€"; // Quelldatei UTF-8 kodiert
                    

                    was schon der Kompiler nicht durchgehen lässt. Siehe Artikel

                    Ja, aber die Begründung ist falsch. char c = "a" wird auch vom Compiler bemängelt. Der Grund ist nicht, dass "€" bei UTF-8-Kodierung mehrere Bytes benötigt, sondern dass Doublequotes einen Pointer auf einen C-String erzeugen. Was du meinst ist char e = '€' - hier ist deine Begründung richtig.

                    Und nochwas: uint8_t *binary - don't do that. C gibt dir nur diese eine Garantie: signed charshort intintlong intlong long int. Es ist nicht garantiert, dass uint8_t == unsigned char. Praktisch ist es heutzutage überall der Fall, aber es muss nicht so sein. Die Datentypen existieren aus einem Grund. Wenn du char meinst, benutze auch char.

                    LG,
                    CK