[C/C++] Datei Byteweise einlesen

Dieses Thema im Forum "Programmierung & Entwicklung" wurde erstellt von zYco, 23. Oktober 2010 .

Schlagworte:
Status des Themas:
Es sind keine weiteren Antworten möglich.
  1. 23. Oktober 2010
    Zuletzt von einem Moderator bearbeitet: 14. April 2017
    Datei Byteweise einlesen

    Hallo allerseits,

    es geht um folgendes:
    Mir wurde die Aufgabe gestellt, Funk-"Telegramme" auszuwerten, bzw für Menschen lesbar zu machen. Diese Telegramme werden von irgendeinem Gerät der Firma für die ich arbeite versendet, spielt aber auch keine Rolle. Diese Telegramme liegen als Logs vor. Ich soll jetzt also ein Programm schreiben, was so ein Log durchgeht, die nötigen Informationen herausfischt und diese dann formattiert in eine .txt schreibt.

    Im moment bekomme ich es aber noch nicht einmal hin, die Datei richtig einzulesen. Im Hexeditor würde ein Beispieltelegramm so aussehen:
    Bild

    Wenn ich das mit meinem Programm einlese und ausgebe sieht das so aus:
    Bild


    Der Code der das einlesen realisiert sieht so aus:
    Code:
    char* putInArray(FILE* file, char* array) {
    
     for (int i = 0; i <= 253; i++) {
     char a = fgetc(file);
     array[i]=a;
     i++;
     }
    
     for(int j=0; j<254; j++){
     cout << array[j];
     }
    
     return array;
    };
    So richtig gefällt mir das aber so nicht.
    Am liebsten würde ich es einfach Byteweise herauslesen und hexadezimal darstellen. So dass ich als Output genau das bekomme, was mir der Hexeditor anzeigt, mit jeweils einem Byte in einem Arrayelement das wäre am besten. Meinen Recherchen haben allerding keine für mich verständliche Lösung gebracht. Ich habe mit c++ kaum Erfahrung und stoße da relativ schnell an meine Grenzen. Hätte vielleicht hier jemand die Muße eine genaue Erklärung zu geben, wie ich das am besten Byteweise auslesen kann?
     
  2. 23. Oktober 2010
    AW: Datei Byteweise einlesen

    Du liest es bereits Byteweise aus. Soll das Telegramm für einen Menschen lesbar sein würde ich sagen filterst Du einfach alles heraus was keine Zahl, kein Buchstabe oder kein Sonderzeichen ála - . , oÄ ist.

    Siehe Null-terminated byte strings - cppreference.com
     
  3. 23. Oktober 2010
    AW: Datei Byteweise einlesen

    Du verwendest kein C++...

    guck mal da: Galileo Computing :: C von A bis Z &ndash; 16 Ein-/Ausgabe-Funktionen

    musst das file als binary öffnen und speichern würde ich das zeug in unsigned char...

    als hex ausgeben ist einfach mit sprintf(buffer, "hex %X",char)
     
  4. 23. Oktober 2010
    AW: Datei Byteweise einlesen

    Inwiefern ist das kein c++?
    Ich hab nicht die Zeit und seh auch keinen wirklichen Grund mich jetzt groß in C++ einzuarbeiten (bin aber grad dabei das gelinkte zu lesen) und wenn das Programm am Ende nur iwie zusammengeschustert ist, dann ist das auch okay, solange ich verstehe, was passiert und es das macht, was es machen soll.

    Könntest du "file als binary" öffnen konkretisieren bzw. wie könnte so eine Zuweise auf ein Arrayelement dann aussehen?
     
  5. 23. Oktober 2010
    AW: Datei Byteweise einlesen

    Hoi,

    fgetc ist z.B. eine reine C-Funktion, die man in C++ nicht verwenden sollte. Ich hab das mal rein in C++ implementiert:

    Code:
    #include <iostream>
    #include <iomanip>
    #include <fstream>
    #include <vector>
    
    int main()
    {
     std::vector<unsigned char> bytes;
    
     std::ifstream file("test.txt", std::ios::in | std::ios::binary);
    
     if (file.bad())
     {
     std::cout << "Irgendwas hat da wohl nicht geklappt...." << std::endl;
     return 1;
     }
    
     unsigned char tmp = 0;
     while (file >> std::noskipws >> tmp)
     {
     bytes.push_back(tmp);
     }
     file.close();
    
     std::vector<unsigned char>::const_iterator bytes_iter;
     size_t output_counter = 0;
     for (bytes_iter = bytes.begin(); bytes_iter != bytes.end(); ++bytes_iter) 
     {
     // cast auf int ist nötig, da std::hex keine unsigned char ausgibt!
     std::cout << std::setw(2) << std::setfill('0') << std::hex << std::uppercase << static_cast<int>(*bytes_iter) << ' ';
    
     ++output_counter;
     if (output_counter % 8 == 0) 
     std::cout << std::endl;
     }
    
     std::cout << std::endl;
    
     return 0; 
    }
    Die Ausgabe muss man evtl. noch ein wenig anpassen.
     
  6. 23. Oktober 2010
    AW: Datei Byteweise einlesen

    falls du das ganze in c brauchst und da ich immernoch nebenbei c lerne:

    Code:
    #include <stdlib.h>
    #include <limits.h>
    #include <stdio.h>
    
    #define UCHAR unsigned char
    #define UINT unsigned int
    
    UCHAR* file_get_binary(const char*, size_t*);
    
    int main(void)
    {
     size_t size;
     char file[] = "pfad/zur/datei.bin";
     UCHAR* data = file_get_binary(file, &size);
     UINT index = 0;
    
     if(NULL == data)
     return 1;
    
     while(index < size) {
     printf("%04X ", data[index]);
    
     if(++index % 8 == 0)
     puts("");
     }
    
     printf("\ntotal: %u bytes.\n\n", index);
    
     free(data);
    
     return 0;
    }
    
    UCHAR* file_get_binary(const char* name, size_t* size)
    {
     FILE* fp = fopen(name, "rb");
    
     if(NULL == fp) {
     printf("datei \"%s\" nicht gefunden!\n", name);
     return NULL;
     }
    
     fseek(fp, 0, SEEK_END);
     *size = ftell(fp);
     rewind(fp);
    
     UCHAR* data = (UCHAR *) malloc(sizeof(UCHAR) * (*size));
     fread(data, 1, *size, fp);
    
     fclose(fp);
    
     return data;
    }
    
    
     
  7. 23. Oktober 2010
    AW: Datei Byteweise einlesen

    Wah, murdoc. Tu' sowas nicht ;-)

    Lass den User lieber erst die Größe per Funktion erfassen, in dem er als 3. Parameter, den Buffer, einen Null-Zeiger übergibt. Danach kann er ja selber einen passenden Buffer bereitstellen. Das ist sicherer.

    Ala

    Code:
    bool_t file_get_contents( const char *filename, size_t *size, char *buffer ) {
     //
     // Erfasse Größe
     //
    
     if(buffer == NULL) {
     return false;
     }
    
     //
     // Erledige Aufgabe
     //
     return false;
    }
    PS bool_t existiert so nicht, könnte aber ein einfaches enum sein.
     
  8. 23. Oktober 2010
    AW: Datei Byteweise einlesen

    ok, aber muss er denn nicht zuerst die größe der datei wissen (in bytes) um einen passenden buffer bereit zu stellen?

    wo genau könnte man in meinem fall schadcode ausführen?
     
  9. 23. Oktober 2010
    AW: Datei Byteweise einlesen

    Nein, es geht um den alloziierten Buffer aus deiner Funktion. Um sowas zu vermeiden setzt er, wenn ein NULL-Zeiger als Buffer übergeben wird (3. Param), nur die Größe und beendet die Funktion. Nun weißt Du ja, wie groß die Datei ist und kann selbstständig einen Buffer alloziieren und ihn der Funktion übergeben.

    Achja, für größere Dateien sollte man diese Art des Lesens einer Datei vermeiden.
     
  10. 24. Oktober 2010
    AW: Datei Byteweise einlesen

    Ich danke euch für eure Antworten, werde die Aufgabe aber wohl jetzt in offensichtlicher Ermangelung an Kompetenz abgeben. =D
     
  11. Video Script

    Videos zum Themenbereich

    * gefundene Videos auf YouTube, anhand der Überschrift.