Hexdump aus Programm erzeugen?



  • asdqweyxc schrieb:

    Nein, das ist unmöglich. 🙄

    Unter Linux gibt es das. Hexdump in Konsole eingeben.

    0x0ERROR



  • Guckst du hier. Oder du hackst dir halt selbst die paar Zeilen zusammen um eine Eingabedatei Hexadezimal in Bytes zerstueckelt auszugeben. Oder nimm gleich einen Hex-Editor.



  • 0x0ERROR schrieb:

    [...] sollte möglichst mir der Standard-Libarie funktionieren.

    #include <cstdlib>
    #include <cctype>
    #include <string>
    #include <algorithm>
    #include <fstream>
    #include <iostream>
    #include <iomanip>
    
    void usage()
    {
    	std::cout << "Usage: dumpfile [filename]\n" << std::endl;
    }
    
    int main( int argc, char *argv[] )
    {
    	if( argc != 2 ) { std::cerr << "Invalid arguments.\n\n"; usage(); return EXIT_FAILURE; }
    
    	std::string argument( argv[ 1 ] );
    	std::transform( std::begin( argument ), std::end( argument ), std::begin( argument ), std::tolower );
    
    	if( argument == "--help" || argument == "-h" ) { usage(); return EXIT_SUCCESS; }
    
    	std::ifstream input( argument );
    
    	if( !input.is_open() ) {
    
    		std::cerr << "File \"" << argument << "\" could not be opened.\n" << std::endl;
    		return EXIT_FAILURE;
    	}
    
    	int ch = 0;
    
    	for( size_t i = 1; ch = input.get(), input; ++i ) {
    
    		std::cout << "0x" << std::hex << std::setw( 2 ) << std::setfill( '0' ) << ch << ' ';
    
    		if( i == 11 ) i = ( std::cout.put( '\n' ), 0 );
    	}
    
    	std::cout << '\n' << std::endl;
    }
    


  • Schöner Code, Swordfisch, aber leider UB wegen Zeile 19. Ist allerdings leicht zu beheben.

    #include <cstdlib>
    #include <cctype>
    #include <string>
    #include <algorithm>
    #include <fstream>
    #include <iostream>
    #include <iomanip>
    
    void usage()
    {
      std::cout << "Usage: dumpfile [filename]\n" << std::endl;
    }
    
    std::ostream& hexdump(std::ostream& os)
    { return os << "0x" << std::hex << std::setw( 2 ) << std::setfill( '0' ); }
    
    int main( int argc, char *argv[] )
    {
      if( argc != 2 ) { std::cerr << "Invalid arguments.\n\n"; usage(); return EXIT_FAILURE; }
    
      std::string argument;
      { std::locale loc; while (*argv[1]) argument.push_back(std::tolower(*argv[1]++, loc)); }
    
      if( argument == "--help" || argument == "-h" ) { usage(); return EXIT_SUCCESS; }
    
      if (std::ifstream input{ argument }) {
        std::for_each(std::istreambuf_iterator<char>(input.rdbuf()), std::istreambuf_iterator<char>{},
                      [](char c){static int i=0; std::cout << hexdump
                                                           << static_cast<unsigned int>(c)
                                                           << ((i=(i+1)%11) ? ' ':'\n');}); 
        std::cout << '\n' << std::endl;
      } else {
        std::cerr << "File \"" << argument << "\" could not be opened.\n" << std::endl;
        return EXIT_FAILURE;
      }
    }
    


  • wozu std::tolower? Imherhin soll das 'n Dateiname sein!! 😕
    Und optional ist das Argument auch nicht.



  • Wegen --help bzw. -h .



  • Hab jetzt den COde versucht, aber ausgegeben werden nur ca. 30 Zeilen
    von 30'000. Kann man die Zeilenanzahl erhöhen.

    0x0ERROR


  • Mod

    0x0ERROR schrieb:

    Hab jetzt den COde versucht, aber ausgegeben werden nur ca. 30 Zeilen
    von 30'000. Kann man die Zeilenanzahl erhöhen.

    Prüf auf Dateiende anstatt auf Nullzeichen.

    Swordfish schrieb:

    Wegen --help bzw. -h .

    Dir ist aber bekannt, dass es viele case-sensitive Dateisysteme gibt und die auch durchaus sehr verbreitet sind?



  • SeppJ schrieb:

    0x0ERROR schrieb:

    Hab jetzt den Code versucht, aber ausgegeben werden nur ca. 30 Zeilen
    von 30'000. Kann man die Zeilenanzahl erhöhen.

    Prüf auf Dateiende anstatt auf Nullzeichen.

    Wie macht man das?
    Hab derzeit folgenden Code:

    void hexdump(char data[]) {
    	string name;
    	for(int i = 0; data[i] != '\0';i++) {
    	name += data[i];
    	}
        string argument( name ); 
        transform( begin( argument ), end( argument ), std::begin( argument ), tolower );
    
        ifstream input( argument ); 
        int ch = 0;
        for( size_t i = 1; ch = input.get(), input; ++i ) { 
    
            cout << hex << setw( 2 ) << setfill( '0' ) << ch; 
            if( i == 32 ) i = ( cout.put( '\n' ), 0 ); 
        } 
    	cout << endl;
    }
    

    0x0ERROR


  • Mod

    SeppJ schrieb:

    Dir ist aber bekannt, dass es viele case-sensitive Dateisysteme gibt und die auch durchaus sehr verbreitet sind?

    Und selbst bei case-insensitiven Dateisystemen ist das für die Konvertierung zuständige Locale nicht notwendigerweise identisch mit dem Locale, mit dem das Program läuft.


  • Mod

    edit: Hatte eine Kleinigkeit im Code übersehen*, es sollte eigentlich passen.
    edit2: Ich kann dein Problem nicht nachvollziehen. Die Ausgabe aller Testfälle ist vollständig, bis auf eventuelle Kovertierungen auf einigen Systemen durch das fehlende binary beim Dateiöffnen (oder ist das gewünscht?). Kannst du dein Problem genauer beschreiben?

    *: @Swordfish: Ich mag deinen Stil nicht. Schwer zu lesen.



  • Ich versuche ein Foto zu öffnen. Dabei werden die ersten 30 Zeilen(32 Zahlen pro Reihe) ausgegeben. Bei Programmen (*.exe) genauso.

    0x0ERROR


  • Mod

    Gehst du auch korrekt mit deinem Terminal um? 30 Zeilen klingt verdächtig nach einer typischen Terminalauflösung.



  • Ich starte das Programm direkt aus der IDE(Visual Studio).

    0x0ERROR



  • Swordfish schrieb:

    std::transform( std::begin( argument ), std::end( argument ), std::begin( argument ), std::tolower );
    

    Wirklich ub?

    camper schrieb:

    SeppJ schrieb:

    Dir ist aber bekannt, dass es viele case-sensitive Dateisysteme gibt und die auch durchaus sehr verbreitet sind?

    Und selbst bei case-insensitiven Dateisystemen ist das für die Konvertierung zuständige Locale nicht notwendigerweise identisch mit dem Locale, mit dem das Program läuft.

    Daran hab' ich leider nicht gedacht. 😞

    SeppJ schrieb:

    Die Ausgabe aller Testfälle ist vollständig, bis auf eventuelle Kovertierungen auf einigen Systemen durch das fehlende binary beim Dateiöffnen (oder ist das gewünscht?)

    Nein, nicht erwünscht, weiterer Lapsus.

    SeppJ schrieb:

    Ich mag deinen Stil nicht. Schwer zu lesen.

    Auf ~40 Zeilen? Pointers?



  • Hast du auch mal rechts an der Scroll-Leiste gezogen, um die Ausgabe durchzuscrollen?


  • Mod

    Swordfish schrieb:

    Swordfish schrieb:

    std::transform( std::begin( argument ), std::end( argument ), std::begin( argument ), std::tolower );
    

    Wirklich ub?

    wüsste nicht, wieso.


  • Mod

    Swordfish schrieb:

    SeppJ schrieb:

    Ich mag deinen Stil nicht. Schwer zu lesen.

    Auf ~40 Zeilen? Pointers?

    Nein, ich meine so "Hackerschreibweisen" mit Kommaoperator. Paradebeispiel:

    if( i == 11 ) i = ( std::cout.put( '\n' ), 0 );
    

    Das hat keine Vorteile gegenüber

    if( i == 11 )
    {
     std::cout.put( '\n' );
     i = 0;
    }
    

    außer dass es vermeintlich 1337 ist. Es ist aber vor allem unleserlich.



  • Hat niemand eine Lösung?
    Wenn ich die Ausgaben in eine Datei leite kommt
    das gleiche heraus.

    0x0ERROR



  • SeppJ schrieb:

    edit2: Ich kann dein Problem nicht nachvollziehen. Die Ausgabe aller Testfälle ist vollständig, bis auf eventuelle Kovertierungen auf einigen Systemen durch das fehlende binary beim Dateiöffnen (oder ist das gewünscht?). ...

    Das hat auf Windows-Systemen auch etwas mit Ctrl-Z zu tun.


Anmelden zum Antworten