erste 4 Byte aus Hexfile in INT konvertieren



  • Wenn du 4 Bytes in ein int verwandeln moechtest, dann solltest du diese erstmal speichern, z.B. in einem Array.



  • ich weis, das Problem ist nur ,dass ich die 4 Bytes nicht herausbekomme, sonst würde ich sie ja in ein Array speichern.

    Das speichern ist ja nicht das Problem,dies in der Schleife zu tun.
    Nur wenn ich das in meinem Code mache speichert er nur mist!


  • Mod

    daffi schrieb:

    Nur wenn ich das in meinem Code mache speichert er nur mist!

    Dann zeig betreffenden Code doch mal!



  • Endian beachten!



  • Zur Zeit siehts so aus:

    Ich nehme mir den Char (1 Byte) und versuche mit Bitschiebeoperationen jeweils die einzellnen Zeichen in ein Char Array zu speichern.

    #include <iostream>
    #include <fstream>
    
    using namespace std;
    
    int main()
    {
        char array[8];
        char c;
    
        ifstream quelle;
        quelle.open("C:\\Users\\Daffi\\Desktop\\Bearbeiten2", ios::in | ios::binary );
        if (!quelle)                              // Fehler beim Öffnen?
            cerr << "Eingabe-Datei kann nicht geöffnet werden\n"; 
    
        int i=0;
        while (quelle.get(c)){
    
           array[i]=c>>4;
           array[i+1]=c<<4;
           i += 2;
       }
    
        cout<<endl<<(int)array;
    
        quelle.close();
        getchar();
        return 0;
    }
    


  • array[i]=c>>4;
           array[i+1]=c<<4;
    

    Was bezweckst du damit?

    Und die Funktion, nach der du suchst, ist wahrscheinlich read . open hast du ja auch gefunden. Ansonsten empfehle ich dir, lieber ein C++ Buch zu lesen.



  • Wie gesagt im hexeditor zeit er mir 8 Zeichen an, also 4 Byte.
    1 char=1 Byte also verschiebe ich es immer um 4 Bit und speichere mir den darin enthaltenen Wert.
    Ja mit read hat ich es auch mal kurz versucht das klappte auch nicht,ka wieso...
    Ich probiere es nochmal.



  • daffi schrieb:

    Wie gesagt im hexeditor zeit er mir 8 Zeichen an, also 4 Byte.
    1 char=1 Byte also verschiebe ich es immer um 4 Bit und speichere mir den darin enthaltenen Wert.
    Ja mit read hat ich es auch mal kurz versucht das klappte auch nicht,ka wieso...
    Ich probiere es nochmal.

    Was auch immer du dir dabei gedacht hast, es ist falsch.



  • Sooooo,

    Ich habe es hinbekommen das die Ausgabe,sprich das cout das macht was ich will.
    Bloß wie bekomme ich diesen Wert nun auf eine Variable?
    Sprich einen 1 byte Puffer, welcher mir diesen Ausdruck speichert: cout<<hex<<(int)buffer[i];

    #include <iostream>
    #include <fstream>
    
    using namespace std;
    
    int main()
    {
        char buffer[4]={0};
    
        ifstream quelle;
        quelle.open("C:\\Users\\Daffi\\Desktop\\Bearbeiten2", ios::in | ios::binary );
        if (!quelle)                              // Fehler beim Öffnen?
            cerr << "Eingabe-Datei kann nicht geöffnet werden\n"; 
    
            quelle.read(buffer,4);
    
            for (size_t i=0;i<4;i++){
                 cout<<hex<<(int)buffer[i];
    
             }
    
        quelle.close();
        getchar();
        return 0;
    }
    


  • Probier doch mal als buffer gleich int zu nehmen. 😉



  • Sprich einen 1 byte Puffer,

    Ich dachte du wolltest 4 Byte in eine einzige Zahl umwandeln.



  • Nick Unbekannt schrieb:

    Probier doch mal als buffer gleich int zu nehmen. 😉

    Geht nicht, da read ein CHar Array Vorraussetzt.

    Ich dachte du wolltest 4 Byte in eine einzige Zahl umwandeln.

    Ja ist auch der Sinn.
    Ich hab aber lediglich hinbekommen den Hexa String überhaupt mal richtig einzulesen.

    Das Array sieht immo so aus:

    buffer: {0, 0, 4, 62}
    Soll Ergebnis ist {0, 0, 4, 3e}

    Daraus dann ein Int zu bilden ist nicht das Problem, nur dahin komme ich leider nicht!



  • daffi schrieb:

    Nick Unbekannt schrieb:

    Probier doch mal als buffer gleich int zu nehmen. 😉

    Geht nicht, da read ein CHar Array Vorraussetzt.

    Und warum castest du nicht den Zeiger? Oder wenn es unbedingt sein muss, mach eine Union:

    typedef union {
        int wert;
        char bytes[4];
    } LeseHelfer;
    
    LeseHelfer meinwert;
    read(meinwert.bytes, 4);
    cout << meinwert.wert;
    


  • Vicious Falcon schrieb:

    Endian beachten!

    Außerdem kannst du mit einem Cast immer eine beliebige (Byte-) Anzahl von Daten korrekt einlesen.



  • Nick Unbekannt schrieb:

    daffi schrieb:

    Nick Unbekannt schrieb:

    Probier doch mal als buffer gleich int zu nehmen. 😉

    Geht nicht, da read ein CHar Array Vorraussetzt.

    Und warum castest du nicht den Zeiger? Oder wenn es unbedingt sein muss, mach eine Union:

    typedef union {
        int wert;
        char bytes[4];
    } LeseHelfer;
    
    LeseHelfer meinwert;
    read(meinwert.bytes, 4);
    cout << meinwert.wert;
    

    Probiere es aus und du wirst sehen das er absoluten Mist da rein schreibt.
    Hab ich alles auch schon probiert ...

    Bei dir kommt das raus: 3e0400000 ...
    ist nicht ganz das was ich suche,dennoch danke!

    Was mich aber bei dem union noch interessiert,wo weist du der Variable wert einen Wert zu?



  • daffi schrieb:

    Probiere es aus und du wirst sehen das er absoluten Mist da rein schreibt.
    Hab ich alles auch schon probiert ...

    Ich weiß, dass das kein Mist ist. 😉

    daffi schrieb:

    Bei dir kommt das raus: 3e0400000 ...
    ist nicht ganz das was ich suche,dennoch danke!

    Den Tipp mit der Endianness hast du beherzigt?

    daffi schrieb:

    Was mich aber bei dem union noch interessiert,wo weist du der Variable wert einen Wert zu?

    Rate mal was Union heißt? 😉 Die beiden Werte haben den selben Speicherbereich. Du umgehst damit lediglich einen Cast.

    Tipp:
    Um das Problem besser verstehen zu können, schreibe doch einfach erstmal ein int mit write in eine Datei und öffne diese mit einem Hexeditor. Dann sollte auch die Sache mit der Endianness klarer werden.



  • Ok ich sehe das das mit dem Union gar net so doof ist ...
    die Werte sind alle nur verkehrt herum!
    Das meint ihr mit dem Endian.

    Verstehen tue ich den Artikel nicht wirklich.
    Handelt es sich dabei wirklich um eine Computerabhängige Speicherung von Werten?

    Dann wäre es bei mir wohl der little Endian!

    Soll ich nun das Array einfach umsortieren?

    EDIT:

    Habs gefunden ...
    Der Code geht nun.
    Nur die Conversion hab ich noch nicht richtig kapiert.
    Kann mir das noch mal jemand mit eigenen Worten sagen?

    Danke für eure Mühen,Daffi

    int INT_little_endian_TO_big_endian(int i)
    {
        return((i&0xff)<<24)+((i&0xff00)<<8)+((i&0xff0000)>>8)+((i>>24)&0xff);
    }
    
    int main()
    {
        int buffer[4]={0};
    
        ifstream quelle;
        quelle.open("C:\\Users\\Daffi\\Desktop\\Bearbeiten2", ios::in | ios::binary );
        if (!quelle)                              // Fehler beim Öffnen?
            cerr << "Eingabe-Datei kann nicht geöffnet werden\n"; 
    
            typedef union {
                int wert;
                char bytes[4];
            } LeseHelfer;
    
            LeseHelfer meinwert;
            quelle.read(meinwert.bytes, 4);
            meinwert.wert=INT_little_endian_TO_big_endian(meinwert.wert);
            cout <<meinwert.wert;
    
        quelle.close();
        getchar();
        return 0;
    }
    


  • daffi schrieb:

    Ok ich sehe das das mit dem Union gar net so doof ist ...
    die Werte sind alle nur verkehrt herum!
    Das meint ihr mit dem Endian.

    Korrekt

    daffi schrieb:

    Verstehen tue ich den Artikel nicht wirklich.
    Handelt es sich dabei wirklich um eine Computerabhängige Speicherung von Werten?

    Was verstehst du nicht? Die Endianness hängt von der CPU ab.

    daffi schrieb:

    Dann wäre es bei mir wohl der little Endian!

    Ja!

    daffi schrieb:

    Soll ich nun das Array einfach umsortieren?

    Nein, warum? Du hast doch deinen int .

    Oder meintest du, die Daten sind in Big-Endian gespeichert? Dann musst du sie drehen. Du kannst dafür aber die Netzwerkfunktion ntohl() verwenden,



  • MH, das Problem ist das das Programm auf diversen Rechnern läuft und somit es auch naheliegt,dass vllt der Endian sich ändert.
    Kann man dem iwie vorbeugen?


  • Mod

    daffi schrieb:

    MH, das Problem ist das das Programm auf diversen Rechnern läuft und somit es auch naheliegt,dass vllt der Endian sich ändert.
    Kann man dem iwie vorbeugen?

    Ja. Auf undefiniertes verhalten wie durch reinterpret_cast und unions verzichten und stattdessen rechnen. Die Elemente deines Arrays stellen Ziffern einer Zahl im 256er System dar (oder genauer gesagt im 2 hoch CHAR_BIT System), damit kannst du dir ganz einfach ausrechnen, welchen Wert die Zahl hat.


Anmelden zum Antworten