Char pointer auf unsigned long variable casten



  • Hallo Leute,

    ich stehe mal wieder vor einem kleinen Problemchen. Ich habe zunächst aus einer Binary Datei ein char-array ausgelesen und aus diesem dann den Inhalt auf eine unsigned long Variable geschrieben. Der Code sah so aus:

    binary_file.read(char_array, 4);
    unsigned_long_variable = *((unsigned long*)char_array);
    

    Jetzt möchte ich dies genau umgekehrt machen. Also ich möchte eine unsigned long variable wieder in eine binary-datei schreiben. Da die write-Funktion ja aber nur char* nimmt, wäre die Frage wie ich das anstelle. Ich habe so etwas probiert:

    unsigned long number = 20000;
    char *char_array = (char*) &number;
    

    Dies funktioniert formal auch. Nun meine Frage: Wenn ich jetzt

    file.write(char_array,4);
    

    verwende, habe ich die long Variable nun korrekt in die Datei geschrieben?
    Bitte entschuldigt wenn meine Begrifflichkeiten nicht ganz korrekt sind. Bin aber C++ technisch einfach noch nicht so der Experte.

    Danke für Eure Hilfe!
    Beste Grüße
    rob


  • Mod

    Sofern sizeof(long) == 4 ist, ist das korrekt. Bei mir ist es aber beispielsweise 8. Bei mir würde dein Code also nicht funktionieren. Aber vielleicht ist das ja auch gar nicht deine Absicht, portabel zu sein, wollte es nur gesagt haben.

    A propos Kompatibilität: Wenn du das so machst, sind die Dateien natürlich nur dann von Maschine zu Maschine übertragbar, wenn das unterliegende Zahlenformat der Maschinen kompatibel ist. Da kommt es nicht nur auf die Länge an (siehe oben), sondern auch die Sortierung (und in exotischen Fällen auch die Codierung der Zahlen an sich) kann unterschiedlich sein.



  • Hey,

    danke für Deine Antwort. Die Daten müssen tatsächlich nicht auf eine andere Maschine übertragbar sein. Allerdings wäre es interessant wovon das abhängt ob unsigned long 4 byte groß ist oder 8. Kann ich aber wahrscheinlich auch Googlen, dann musst Du dir nicht die Mühe machen 🙂 Danke aber für den Hinweis. Das mit der Sortierung habe ich nicht so recht verstanden aber auch da starte ich mal eine Internetrecherche bevor ich blöd rumfrage. Mir ist direkt nach dem Posten auch aufgefallen, dass ich ja selbst testen kann ob das oben funktioniert in dem ich einfach den char* zurück zu einem unsigned long* caste und den Inhalt auslese. Manchmal hat man eben ein Brett vorm Kopf. 😉

    Besten Danke nochmal,
    Grüße
    rob


  • Mod

    rob...o.0 schrieb:

    Hey,

    danke für Deine Antwort. Die Daten müssen tatsächlich nicht auf eine andere Maschine übertragbar sein. Allerdings wäre es interessant wovon das abhängt ob unsigned long 4 byte groß ist oder 8.

    Von Hardware und Software. Im großen und ganzen gibt es vier übliche Fälle und viele exotische Sonderfälle, die ich nicht erwähne:
    -Windows, 32-Bit-Programme: long hat 4 chars
    -Windows, 64-Bit-Programme: long hat 4 chars
    -unixartige, 32-Bit-Programme: long hat 4 chars
    -unixartige, 64-Bit-Programme: long hat 8 chars

    Kann ich aber wahrscheinlich auch Googlen, dann musst Du dir nicht die Mühe machen 🙂 Danke aber für den Hinweis. Das mit der Sortierung habe ich nicht so recht verstanden aber auch da starte ich mal eine Internetrecherche bevor ich blöd rumfrage.

    https://en.wikipedia.org/wiki/Endianess

    Mir ist direkt nach dem Posten auch aufgefallen, dass ich ja selbst testen kann ob das oben funktioniert in dem ich einfach den char* zurück zu einem unsigned long* caste und den Inhalt auslese. Manchmal hat man eben ein Brett vorm Kopf. 😉

    Ja, das geht und wäre ein besserer Weg. Wollte ich zuerst erwähnen, hatte aber irgendwie überhaupt nichts mit deiner Frage zu tun, daher habe ich es gelassen 🙂



  • Wenn die Größe garantiert 4 Byte sein soll dann solltest du den uint32_t Typ (cstdint Header) verwenden statt unsigned long . Zu der sortierung der Bytes: https://de.wikipedia.org/wiki/Byte-Reihenfolge
    Theoretisch muss man sich auch noch Sorgen machen um andere Zahlendarstellungen aber praktisch sind die meisten Systeme Little-Endian und nutzen das Zweierkomplement zur Darstellung.



  • Bleibt noch zu bemerken, dass der Umweg über ein char array/pointer nicht nötig ist weil du sowieso irgendwo casten musst. Wo du das machst ist völlig egal ...

    unsigned long value;
    
    binary_file.read((char*)&value, sizeof(value));
    ...
    binary_file.write((char*)&value, sizeof(value));
    

    In C++ sollte man natürlich reinterpret_cast<>() verwenden 😉



  • rob...o.0 schrieb:

    Die Daten müssen tatsächlich nicht auf eine andere Maschine übertragbar sein.

    Noch nicht.



  • osdt schrieb:

    In C++ sollte man natürlich reinterpret_cast<>() verwenden 😉

    und bei write const char*


Log in to reply