16-Bit im Zweierkomplement Zahl aus Datei lesen



  • Hallo zusammen,

    ich habe ein wahrscheinlich simples Problem.
    Ich möchte eine vorzeichenbehaftete 16-Bit-Zahl (Big Endian) mit fstream aus einer
    Datei lesen.
    Wie mache ich das am besten?
    Ich lese 2 Byte in ein char-Array. Anschliessend möchte ich die Werte natürlich
    (z. B.) in einem unsigned int speichern. Gibt es da vorgefertigte Methoden
    in der Standardlibrary oder muss ich die Werte selbst zusammen rechnen und
    bei einer negativen Zahl die restlichen Bits auf eins setzen?

    Gruß,
    *Cpp-Anfänger*



  • Warum liest Du nicht direkt das unsigned int per Stream ein? Wieso der Umweg über die chars?



  • Öhm...

    Wenn ich es als int einlese habe, werden nicht zwangsläufig 2 Bytes eingelesen, oder?

    Die Größe von int ist doch nicht zwangsläufig 2 Byte.
    Liest er denn immer nur 2 Bytes?

    Gruß,
    *Cpp-Anfänger*



  • Na ja, wenn es portabel sein soll, musst Du natürlich systemspezifische Typedefs verwenden. Das musst Du beim Einlesen aber sowieso, denn es kann Dir theoretisch auch nicht garantiert werden, dass ein unsigned int immer dieselbe Anzahl an chars hat.



  • Danke Konrad Rudolph!!!



  • Auf den gängigen Systemen ist int aber 32bit! short wäre 16bit...

    Grüße,

    Martin



  • Cpp-Anfänger schrieb:

    Ich möchte eine vorzeichenbehaftete 16-Bit-Zahl (Big Endian) mit fstream aus einer
    Datei lesen.
    Wie mache ich das am besten?
    Ich lese 2 Byte in ein char-Array. Anschliessend möchte ich die Werte natürlich
    (z. B.) in einem unsigned int speichern. Gibt es da vorgefertigte Methoden
    in der Standardlibrary oder muss ich die Werte selbst zusammen rechnen und
    bei einer negativen Zahl die restlichen Bits auf eins setzen?

    wieso in 'unsigned int' speichern, wenn die werte 'signed' sind?
    wegen der festgelegten big endianess solltest du besser die bytes einzeln in einen vorzeichenbehafteten 16-bit wert einlesen. erst das erste, dann 8 mal links schieben und das zweite byte dazu odern. eine andere möglichkeit wäre, immer zwei bytes einzulesen und dann mit 'htons' umzudrehen. htons tauscht die bytes auf little endian plattformen, auf big endian systemen macht es nichts.
    hast du keinen 16-bit int, kannst du dir auch einen basteln:

    struct {int value :16;} i16;
    

    i16.value ist dann ein 16-bittiger signed integer

    i16.value = ...;   // erstes byte
    i16 <<= 8;         // nach links wegen big endian
    i16 |= ...;        // zweites byte dazu odern
    

    passt immer
    🙂



  • @JimmydaMage: stimmt, sogar ne Mindestgröße von 32bit

    @Apeman: Meinte natürlich signed

    Vielen dank euch beiden 🙂



  • So kann man's auch machen

    #include <fstream>
    union swap
    {
        unsigned char a[2];
        short b;
    };
    
    int main()
    {
        std::ifstream ein("c:\\test.bin", std::ios::binary);
        swap lee;
        ein >> lee.a[0];   //Wenn es im Big Endian Format in der Datei steht
        ein >> lee.a[1];   //muesste man, um nach Little Endian zu wechseln, 
        short test = lee.b;// zuerst nach lee.a[1] einlesen und dann nach lee.a[0]
    }
    

    😉



  • egon2 schrieb:

    So kann man's auch machen

    naja, da wär' ich vorsichtig. ich glaube, es ist nicht garantiert, dass sich das char-array und der short in der union genau überdecken. ausserdem muss ein 'short' nicht immer 16 bits haben.
    🙂



  • Naja, ein short müsste doch immer 2 Bytes haben, läuft nicht zwangsweise auf 16 Bits hinaus, aber auf nicht allzu-exotischen Dateisystemen muss die Dateigröße ja auch byte-aligned sein. Damit gibt es dann ja keine 16-Bit-Datei (außer ein char ist genau 16 bits groß).
    Naja, ich denke sowieso, der OP will für ein 8-Bit-Char-System programmieren..



  • Badestrand schrieb:

    Naja, ein short müsste doch immer 2 Bytes haben,

    Mit solchen "immer" Aussagen wäre ich bei Standard-Fragen vorsichtig - ein short hat mindestens 16 Bit, kann/darf aber auch größer sein.



  • CStoll schrieb:

    Mit solchen "immer" Aussagen wäre ich bei Standard-Fragen vorsichtig - ein short hat mindestens 16 Bit, kann/darf aber auch größer sein.

    Hm, aber ich dachte ein Byte hätte x Bits und ein short wären 2 Bytes 😕



  • Die einzige "genau" Aussage im Ansi-Standard ist: "Ein char ist 1 Byte groß" (wobei offengelassen wird, wieviel Bit das entspricht). Ansonsten gibt es nur relative Aussagen wie "int ist mindestens so groß wie short" und Angaben zu Mindestgrößen (in Form von Minimalwerten für SHORT_MIN etc).



  • Hach ist das alles merkwürdig.. 😕



  • Badestrand schrieb:

    Hach ist das alles merkwürdig.. 😕

    Wieso? Das Ansi-Kommitee war weitsichtig genug zu erkennen, daß 8-Bit-Rechner nicht das Ende der Fahnenstange sein werden - und hat deshalb die Möglichkeit offengelassen, daß der Compiler die optimalen Datengrößen für sein System festsetzt.

    (in Java wird int immer 4 Byte groß bleiben, selbst wenn wir alle mit 256-Bit-Systemen arbeiten *duck'n'run*)



  • CStoll schrieb:

    (in Java wird int immer 4 Byte groß bleiben, selbst wenn wir alle mit 256-Bit-Systemen arbeiten *duck'n'run*)

    kein grund für *duck'n'run*. it's a feature, not a bug.
    in Java wird es dann wahrscheinlich einen int256 o.ä geben.



  • Und alle zwei Jahre muß man umdenken, wie denn nun die aktuell gültigen Datentypen heißen 🙄

    (aber kehren wir wieder zurück zum Thema - hier geht's immer noch um C++)



  • CStoll schrieb:

    Und alle zwei Jahre muß man umdenken, wie denn nun die aktuell gültigen Datentypen heißen

    nein, warum? die alten datentypen wird es auch noch geben und VM und compiler weden dafür sorgen, dass deren nutzung keine effizienzeinbussen mit sich bringt. nur wir armen C-frickler müssen uns mit variablen datenwortbreiten, manuellem speichermanagement und ähnlichem zeug aus der programmierer-steinzeit, bis zum jüngsten tag herumärgern.
    🙂



  • (ich wußte es, es war ein Fehler, hier das J-Wort zu erwähnen)

    Ein int in C oder C++ wächst mit den verwendeten Prozessoren mit, ein int in Java nicht (und ob er auf 256-Bit-Systemen genauso "einfach" umgesetzt werden kann wie auf heutigen Rechnern, ist die andere Frage). Das hat beides seine Vor- und Nachteile.


Anmelden zum Antworten