erste 4 Byte aus Hexfile in INT konvertieren



  • 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.



  • Die Endianness ist auf den meisten handelsüblichen Rechnern gleich. Bei ARM, x86, x64, überall Little-Endian.
    Zur Sicherheit kannst du dich aber auf eine Endianness festlegen und dann bei Bedarf swappen. Dafür gibt es diese "host to network"-Funktionen die ich dir vorhin vorgestellt habe. Die Netzwerk-Endianness ist Standardmäßig Big-Endian. Die kümmern sich auch darum, herauszufinden welche Endianness dein System hat. Du hast also nichts weiter zu tun, als deinen Wert einmal durch diese Funktion zu führen. Das ganze umgekehrt, wenn du die Werte speichern willst.

    http://www.manpagez.com/man/3/ntohl/
    Steht zwar OSX drunter, die Funktionen gibt es aber auch in Windows und Linux.

    http://msdn.microsoft.com/en-us/library/ms740069(VS.85).aspx



  • SeppJ schrieb:

    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.

    Soweit war ich ja auch schon.
    wie gesagt mein Array hatte den Aufbau: {0,0,4,62}

    Ich habe es nicht hinbekommen das es so aussieht: {0,0,4,3E}

    Dannach kann ich ohne Probleme mit *16^x rechnen...



  • daffi schrieb:

    Soweit war ich ja auch schon.
    wie gesagt mein Array hatte den Aufbau: {0,0,4,62}

    Ich habe es nicht hinbekommen das es so aussieht: {0,0,4,3E}

    Die oberen Werte sind Dezimal und die unteren Hexadezimal, dein Ergebnis stimmt also.

    daffi schrieb:

    Dannach kann ich ohne Probleme mit *16^x rechnen...

    Das hab ich ja noch nie gehört, dass man die Byteorder über die Basis korrigiert. Es ist auch eine ganz schlechte Idee dies zu tun, weil extrem langsam. Und auch rein logisch ist es Unsinn, weil ein float ist nunmal kein int .
    Es gibt dafür Funktionen direkt in der CPU und diese sollten auch dafür genutzt werden. Wäre natürlich interessant, ob der Compiler das so hin optimiert bekommt?
    Bei Übertragungen über das Netzwerk entstehen die selben Probleme, also warum soll man sich dann nicht an ihrer Lösung orientieren?



  • Die oberen Werte sind Dezimal und die unteren Hexadezimal, dein Ergebnis stimmt also.

    Ich weis das es stimmt.Ich will doch nur das in den Array die HEX angabe steht und nicht die Dezimale.
    Damit kann ich gar nix anfangen und umwandeln kann ich es irgendwie auch nicht.



  • daffi schrieb:

    Ich will doch nur das in den Array die HEX angabe steht und nicht die Dezimale.

    Das verstehe ich jetzt nicht? Der angezeigte Wert hat nur für dich zur Visualisierung die Basis 16, bzw 10. Im Array stehen auch weiterhin nur binäre Werte.

    daffi schrieb:

    Damit kann ich gar nix anfangen und umwandeln kann ich es irgendwie auch nicht.

    Schau dir mal an, ob deine Byteswap-Funktion das richtige tut, bzw. bist du dir sicher, dass die Werte in der Datei Big-Endian sind?

    Du musst die Werte übrigens verodern und nicht addieren. Und Right-Shift von signed Werten ist auch keine gute Idee.

    http://de.wikipedia.org/wiki/Zweierkomplement



  • [quote="Nick Unbekannt"]

    daffi schrieb:

    Ich will doch nur das in den Array die HEX angabe steht und nicht die Dezimale.

    Das verstehe ich jetzt nicht? Der angezeigte Wert hat nur für dich zur Visualisierung die Basis 16, bzw 10. Im Array stehen auch weiterhin nur binäre Werte.

    daffi schrieb:

    Damit kann ich gar nix anfangen und umwandeln kann ich es irgendwie auch nicht.

    Ok ich versuche es nochmal anders:

    Ziel ist es eine INT Zahl aus dem Array zu bekommen.
    Mein Ansatz war folgender:

    Das Array nehmen und dann jede Stelle mal 16^x nehmen und so die Zahl zusammensetzen.
    Deshalb bräuchte ich das 3e.

    Ich weis leider keinen Eleganteren Weg um dies zu wandeln.



  • daffi schrieb:

    Ich will doch nur das in den Array die HEX angabe steht und nicht die Dezimale.

    Im int bzw. Array steht eine Zahl, und die ist weder dezimal oder headezimal. Du könntest genausogut soundsoviel Finger zählen oder Steinchen legen. Entscheidend ist, wie Du diese Zahl anzeigst.

    Als standard gibt cout int-Zahlen dezimal aus. Wenn Du sie anders haben willst, kannst Du das umschalten mit:

    cout << hex << meineVariable << endl;
    

    Wenn Du noch etwas mehr Format reinhaben willst, informiere Dich über setw und setfill : http://www.cplusplus.com/reference/iostream/manipulators/setw/.

    Übrigens ist die Endianess auf Power-PC-Prozessoren Big-Endian und damit anders als Intel. Spielt keine Rolle, solange man nur ints miteinander verrechnet, aber, wie Du gesehen hast, wenn man liest oder speichert. Da gibt es nur eines: Ein fixes Format vereinbaren, damit alle Rechner wissen, was in der Datei drinsteht.



  • Was spricht jetzt eigentlich dagegen die "host to network byteorder"-Funktionen zu nutzen, die ich dir vorhin verlinkt habe? Damit brauchst du dir über die Endianness überhaupt keinen Kopf mehr zu machen. Das wird alles für dich erledigt, du musst lediglich sicherstellen, dass auf jedem System diese Funktion zum Schreiben/Lesen in/aus der Datei genutzt werden.



  • Oh Mann.
    Leider ist es nicht so.
    Ich kann diese Zahl nun ebend nicht ausgeben, das wäre ja zu schön.

    quelle.read(buffer, 4);

    cout<<hex<<(int)buffer;

    Spuckt mir nur Mist aus.

    Ich will doch die Zahl auch nicht ausgeben sondern nur die eine Zahl als Variable speichern.
    Einfach nur die Bytes in eine einzige INT variable speichern.



  • daffi schrieb:

    Oh Mann.
    Spuckt mir nur Mist aus.

    Na, wie sieht denn der Mist nun konkret aus?



  • minastaros schrieb:

    daffi schrieb:

    Oh Mann.
    Spuckt mir nur Mist aus.

    Na, wie sieht denn der Mist nun konkret aus?

    28ff2c



  • daffi schrieb:

    28ff2c

    Das ist aber Mist.

    Wenn ich das richtig sehe: Du liest jetzt doch in den Buffer ein? Also das int-Array? Und gibst das aus?

    Wenn Du

    cout<<hex<<(int)buffer;
    

    schreibst, dürfte das die Adresse Deines Arrays sein, nicht dessen Inhalt. Versuch es mit

    cout << hex << buffer[ 0 ];
    


  • Nein leider auch falsch.

    1. Ist es ein Char Araay
    2. Ist buffer[0] schon eine eingelesene Zahl



  • Schau, in dem letzten bekannten Programm war es noch ein int. Wie denkst Du, dass andere Leute, nicht im vollen Besitz hellseherischer Fähigkeiten, ein Programm debuggen sollen, dessen Änderungen noch nicht öffentlich sind?



  • Dann zeig mir mal wo es ein INT war, ich bin gespannt!

    Maximal dort, wo ich es auf raten anderer ändern sollte, letzte Fassung ists auch ein Char!


Anmelden zum Antworten