erste 4 Byte aus Hexfile in INT konvertieren



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



  • daffi schrieb:

    Ja ich bin an das Format gebunden ...

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

    FFS, wenn du nicht mal auf meine Posts inkl. korrekter Lösung antwortest, dann wunder dich net wenn dir irgendwann keiner mehr hilft 😡



  • NewSoftzzz schrieb:

    daffi schrieb:

    Ja ich bin an das Format gebunden ...

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

    FFS, wenn du nicht mal auf meine Posts inkl. korrekter Lösung antwortest, dann wunder dich net wenn dir irgendwann keiner mehr hilft 😡

    So ich bins mal wieder 😉
    Sorry ich hatte deinen Beitrag schlicht und einfach überlesen,da er auf der neuen Seite erschien.

    Ich habe deins ausprobiert und muss sagen es funktioniert sehr gut!

    Kannst du das kurz erklären?
    Danke für die Arbeit!


Anmelden zum Antworten