erste 4 Byte aus Hexfile in INT konvertieren



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



  • Vorherige Seite:

    [b]int[/b] [b]buffer[/b][4]={0};
    

    Diese Seite:

    quelle.read([b]buffer[/b], 4);
    

    Meine Frage:
    Du liest jetzt doch in den Buffer ein? Also das int-Array?

    Deine Antwort:
    1. Ist es ein Char Araay



  • Mh da hab ich bissl geschlampt.
    Das Array ist tot und hat keine bedeutung für diesen Code.
    Habs vergessen heraus zu nehmen.
    Habe aber nie über ein INT Array eingelesen.
    Dort ging das einlesen über das byte[4] Array.



  • Die Bitverschiebungsidee is ja in Ordnung wenn du VORHER auf unsigned long castest, da du sonst durch die Bitverschiebung einen Overflow auslöst.. Und dann musste natürlich noch richtig verschieben.

    unsigned long result = (((unsigned long)byte[0]) << 24) | (((unsigned long)byte[1]) << 16) | (((unsigned long)byte[2]) << 😎 | ((unsigned long)byte[3]);

    Das sollte eigentlich den Trick tun wenn du die 4 bytes richtig eingelesen hast. Allerdings funktioniert das jetzt natürlich nur für deine Quelldatei in der besagten endianness. Wenn du allerdings Kontrolle über die Quelldatei hast bzw. wie die Datei beschrieben wird kannst du den Code auch so lassen. Endianness ist ja nur dann ein Problem wenn man nicht out- und input selber auf einen Standard festlegen kann.

    mfg, René~

    EDIT: Falscher Bitoperator fixed



  • edit: Aussage über cast war falsch. Lieber gelöscht. NewSoftzzzs code ist korrekt.

    Es wurde schon mehrmals die Funktion ntohl( ) empfohlen, die diese Umwandlung erledigt, aber vorher prüft, ob sie auf dem laufenden System überhaupt notwendig ist. vielleicht wäre es jetzt an der Zeit, die entsprechende man-Page man anzusehen (oder Dr. Google zu fragen).



  • #include <iostream>
    #include <fstream>
    #include <stdio.h>
    #include<winsock2.h> //ntohl()
    
    using namespace std;
    
    int INT_little_endian_TO_big_endian(int i)
    {
        return((i&0xff)<<24)+((i&0xff00)<<8)+((i&0xff0000)>>8)+((i>>24)&0xff);
    }
    
    int main()
    {
        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=ntohl(meinwert.wert);
            //meinwert.wert=INT_little_endian_TO_big_endian(meinwert.wert);
            cout <<meinwert.wert;
    
        quelle.close();
        getchar();
        return 0;
    }
    

    Was mache ich falsch?
    Er sagt mir: undefined reference to `ntohl@4'

    Ich kriegs es einfach nicht hin...



  • Du hast den verlinkten Artikel zu der Funktion nicht gelesen?
    Aber um das abzukürzen, du musst unter Windows die Winsock-Library linken, weil dort die Netzwerkfunktionen sind.
    Schreibe einfach unter den includes:

    #pragma comment(lib, "Ws2_32")
    

    Damit linkt Visual Studio die benötigten Funktionen. Beim gcc musst du als Linker-Option -lWs2_32 wahrscheinlich angeben. Kommt letztendlich darauf an, welche Laufzeitbibliothek genutzt wird.



  • Gut Danke, leider kann ichs grad nicht testen.

    Was mich noch interessiert ist wie das ganze ohne den union gehen würde.

    Hat dazu jemand eine Idee?



  • Die Union umgeht einfach nur die Notwendigkeit des Castings. Technisch gesehen passiert bei beiden das gleiche. Die Notwendigkeit besteht nur darin, die Typsicherheit gewährleisten zu können.
    Alternativ kannst du aber auch mit IO-Streams arbeiten, dann werden deine Daten als Texte gespeichert. Damit umgehst du zwar das Problem der Endianness gekonnt, handelst dir aber andere Probleme ein.



  • Nick Unbekannt schrieb:

    Die Union umgeht einfach nur die Notwendigkeit des Castings. Technisch gesehen passiert bei beiden das gleiche. Die Notwendigkeit besteht nur darin, die Typsicherheit gewährleisten zu können.
    Alternativ kannst du aber auch mit IO-Streams arbeiten, dann werden deine Daten als Texte gespeichert. Damit umgehst du zwar das Problem der Endianness gekonnt, handelst dir aber andere Probleme ein.

    welche Probleme handle ich mir damit ein?
    Hast du dafür ein Beispiel?



  • OK, man kann die Notwendigkeit von ntohl( ) auch umgehen, indem man selbst feststellt, welches Endian die eigene Architektur benutzt und dann nach Bedarf die Bytes tauscht:

    Z.B. das hier (aus einem Forum:)

    bool is_big_endian( void )
    {
        int i = 1;
        unsigned char *pc = (unsigned char*)&i;
        return (pc[0] == 0); /* most significant byte is stored first for big_endian */
    }
    

    Andere Frage: Bist Du an dieses binäre Dateiformat gebunden, d.h. ist das eine Vorgabe oder kannst Du das frei bestimmen? In letzten Fall könnte man die Zahlen auch im Klartext einfach in die Datei schreiben (das ist das mit den Streams) und wieder auslesen.



  • Ups, ja natürlich falscher Bitoperator.. War schon spät 😉

    @daffi: Probier mal meinen Code aus, dann brauchst du keine union, keinen ntohl und musst dir nicht um endianness Sorgen zu machen (da wie ich im ersten Post ja lese die Struktur der Datei gegeben ist) sondern musst nur die ersten 4 Bytes der Datei einlesen.

    unsigned char bytes[4];
    
    // bytes einlesen aus datei
    
    unsigned long result = (((unsigned long)bytes[0]) << 24)
      | (((unsigned long)bytes[1]) << 16)
      | (((unsigned long)bytes[2]) << 8)
      | ((unsigned long)bytes[3]);
    


  • minastaros schrieb:

    OK, man kann die Notwendigkeit von ntohl( ) auch umgehen, indem man selbst feststellt, welches Endian die eigene Architektur benutzt und dann nach Bedarf die Bytes tauscht:

    Z.B. das hier (aus einem Forum:)

    bool is_big_endian( void )
    {
        int i = 1;
        unsigned char *pc = (unsigned char*)&i;
        return (pc[0] == 0); /* most significant byte is stored first for big_endian */
    }
    

    Andere Frage: Bist Du an dieses binäre Dateiformat gebunden, d.h. ist das eine Vorgabe oder kannst Du das frei bestimmen? In letzten Fall könnte man die Zahlen auch im Klartext einfach in die Datei schreiben (das ist das mit den Streams) und wieder auslesen.

    Ja ich bin an das Format gebunden ...

    Ok also gibt die Funktion true zurück wenn es big Endian ist und sonst false,richtig?


Anmelden zum Antworten