Ergebnis 1 bis 12 von 12

Thema: C++ Script gibt beim Lesen von datein nur komischen Hexcode aus o.O

  1. #1

    C++ Script gibt beim Lesen von datein nur komischen Hexcode aus o.O

    Hallo ,

    Ich lasse über die variable :

    FILE *datei ;

    eine datei laden mithilfe hier von

    datei = fopen( datei_name, "r" );

    wenn ich nun datei über cout ausgäbe erhalte ich immer nur einen komischen Hexcode -.-

    so steller u.a.

    Code:
    _
    1
    2
    3
    4
    5
    _
    So dar

    Code:
    0x77c2fce0
    o.O kann mir das mal jemand erklähren ?

  2. #2
    Ja, FILE* ist ein Pointer und Pointer werden, wenn man sie ausgibt so dargestellt. Das was du da siehst ist eine Adresse im Speicher.

  3. #3
    1. fopen() ist C Code und nicht C++ Code. Die C++-Variante würde ifstream heißen. (Dies ist die Klasse von der man Objekte zum Einladen von Dateien bildet).

    2. fopen() öffnet nur die Datei und stellt einen Pointer zu dieser Datei her. Damit ist noch kein Inhalt eingelesen worden. Dafür gibt es Funktionen wie fread().

    3. Hexadezimalwerte sind in C/C++ (meist) Speicherstellen. Wenn du so etwas angezeigt bekommst, ist das die Speicherstelle einer Variablen oder sonst eines Objekts im Speicher. Dann hast du wohl einen Pointer anstelle dessen "gepointeten" Wert ausgeben lassen.
    In deinem Fall aber gibst du einen Pointer auf ein Dateiobjekt aus, was überhaupt keinen Sinn (oder zumindest nicht den von dir gewünschten) hat. Du brauchst da noch einen Speicherbereich in den eingelesen wird und musst dann mittels fread() dort Daten aus dem Dateiobjekt "datei" einlesen.

    Ich würde dir aber dennoch die C++ Methode empfehlen, denn diese ist einfacher und auch zeitgemäßer, wenn du sowieso C++ programmieren willst.
    Diese findest du im header "fstream", Klasse hab ich gesagt, ist die ifstream und ofstream (dann gibts afaik auch noch nur fstream und sicher ein paar Abwandelungen, brauchte ich bisher nicht...).

    Ein Beispiel für das Einlesen einer Datei in C++ :
    (Im gleichen Verzeichnis wie der Sourcecode muss eine "Datei.txt" Datei mit beliebigem Inhalt vorhanden sein (mindestens 11 Zeichen)).

    Code:
    #include <fstream>
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        ifstream file("Datei.txt", ios::in);
    
        //Lesemethode 1:
        char variable;
        file>>variable;
    
        //--    
        cout<<variable<<endl;
        //Lesemethode 2:
        char* buffer = (char*) malloc(10);
        memset(buffer, 0, 10);
        file.read(buffer, 9);
    
        //--
        cout<<buffer<<endl;
        
        cin.get();
    
        return 0;
    }
    Die simple Methode ist die erste, dabei werden per Stream-Operatur "<<" aus dem geöffneten "Dateistrom" so viele Byte entnommen, wie in die Variable rechts davon passen. Hier ein Byte, da es eine char Variable ist. Diese Variable nimmt dann den Inhalt an. Sehr mühsam wenn man große Datenmengen auslesen will.
    (Ob man auch Speicherbereiche so angeben kann weiß ich nicht. Jedenfalls ist diese Methode zwar simpel aber Methode 2 würde ich empfehlen).

    Die Methode 2 ließt so viele Byte ein, wie im letzten Parameter angegeben. Vorher muss aber ein Bereich mittels malloc() im Speicher reserviert werden, wo die Daten rein kommen. Wichtig ist hier, dass jeder String mit einem 0-Zeichen (Null) abschließen sollte da es sonst Fehler geben kann und wird. Deshalb musst du ein Byte mehr reservieren als du einlesen willst. Das letzte Zeichen muss 0 sein. Damit ich nicht rumfischen muss im letzten Byte, setze ich vor dem Einlesen per memset() alle Zeichen erst einmal auf 0. Jetzt werden 9 Zeichen in die 10 vorhandenen Stellen eingelesen, die letzte bleibt 0.
    Beim Ausgeben von Speicherstellen kann man über Cout auch einfach den char-Pointer angeben, cout nimmt dann automatisch den Wert an der Speicherstelle, also den String, und gibt nicht die Speicherstelle selbst aus (Das Hexadezimale Zeugs von oben etwa).

    Geändert von Ynnus (08.07.2005 um 18:38 Uhr)

  4. #4
    bitte achtet doch auch bei so einfachen beispielen darauf, dass ihr explizit reservieten speicher auch wieder freigebt ...

    malloc ist uebrigends auch fuer c++ als deprecated anzusehen, und sollte demnach vollstaendig durch den Operator new ersetzt werden.

  5. #5
    Ich finde malloc aber viel schöner.
    (Gibt auch noch calloc, warum auch immer...)

    Dieses new hat für mich nix. Das ist mir zu array-lastig mit den Eckigen Klammern. Ich nutze seltener Arrays seitdem ich den Speicher so mit malloc leicht bereitstellen kann. Früher hab ich da mehr mit Arrays gemacht.

    Was Freigabe betrifft, das übernimmt in der Regel das OS. Ok, man sollte es beispielhafterweise selbst übernehmen, wirklich schädlich ist es aber nicht.

  6. #6
    Man kann auch einen Garbage Collector verwenden - ich finde, daß einer der besten Wege, zu verhindern, daß der Programmierer vergißt, Speicher freizugeben, ist, daß man ihm diese Arbeit abnimmt. (Whee, Kommainferno!) Wenn man nicht gerade ultimative Performanz benötigt stellt ein GC sicher eine brauchbare Alternative zur expliziten Speicherreservierung dar.
    Ein Beispiel für einen C/C++-GC wäre libgc, das unter einer sehr toleranten Lizenz vertrieben wird.


    BTW, kann man mit new mehrdimensionale Arrays reservieren? Ich kenne das nur mit malloc().

    Geändert von Jesus_666 (09.07.2005 um 11:45 Uhr)

  7. #7
    Zitat Zitat von Jesus_666
    BTW, kann man mit new mehrdimensionale Arrays reservieren? Ich kenne das nur mit malloc().
    char** multi = new char*[16];
    for(int i=0;i<16;i++) multi[i] = new char[16];

  8. #8
    Ich erstelle immer eindimensionale und projeziere sie auf 2 Dimensionen. Das resultiert daraus, dass ich es einfach nicht vernünftig hinbekommen habe, ein zweidimensionales Array dynamisch größer oder kleiner zu machen.

  9. #9
    Zitat Zitat von Ynnus
    Was Freigabe betrifft, das übernimmt in der Regel das OS. Ok, man sollte es beispielhafterweise selbst übernehmen, wirklich schädlich ist es aber nicht.
    Gut für "normale"-BS's mag das ja stimmen, aber: "Informatiker schliessen ja auch ihre Dateien selbst" und free ist z.B. auch sehr Praktisch wenn es sich nur um ein spartanisches BS auf dem Target handelt. z.B. auf einem µC (Ich weiss, damit werden wohl nicht so viele hier zu tun haben, ich wollte es aber nur kurz anschneiden).

    Da dann unter Umständen niemand den Speicher wieder freigibt nachdem er einmal vergeben ist.

    Andererseits verkompliziert es den Antwort-Code für den Fragenden, und hilft somit vielleicht nicht immer wirklich weiter.

  10. #10
    BTW, es gibt sogar Gelegenheiten, wo es explizit erwünscht ist, daß Speicher nicht freigegeben wird.
    Für Linux gibt es ein Kernelmodul, das es erlaubt, Linux auf fehlerhaftem RAM zu betreiben. Man ermittelt mit Memtest86 die Position der defekten Speicherzellen und übergibt sie dem Kernelmodul. Das Modul belegt dann die entsprechenden Speicherbereiche und gibt sie nicht mehr frei. Damit hat das System zwar weniger Speicher zur Verfügung, läuft aber stabil.

  11. #11
    das OS gibt idR nicht automatisch von einem Programm alloziierten aber nicht freigegebenen Speicher frei, da Programmen ja auch erlaubt wird, ueber gemeinsame Speicherbereiche Daten auszutauschen. Demzufolge bleiben idR die Speicherlecks erhalten, bis ein Neustart des Rechners erflogt.

    Die gaengige Programmierpraxis ist demzufolge, JEDES ?alloc hat ein free, JEDES new hat ein delete. Alles andere ist beschissener Programmierstil (ausser in den seltenen Faellen, die Jeez ansprach) und wird einen bei groesseren Projekten in Teufels Kueche bringen. Gerade Anfaenger sollten deshalb aufs schaerfste zur akribischen Einhaltung gezuechtigt werden, lesbarkeit hin oder her. Auf Fehlerfangen mit Exceptions kann man in Beispielcode mMn verzichten, aber eine korrekte Speicherverwaltung ist ein absolutes MUSS.

  12. #12
    Ich bekenne mich ja schuldig.
    Ich vergess ja leider selbst zu gern immer mal wieder den allocierten Speicher wieder freizugeben. In der letzten Zeit hab ich extra darauf geachtet, dass ich, wenn ich Speicher mehrfach reserviere, den vorherigen erst wieder freigebe, aber ob das konsequent im ganzen Programm so ist weiß ich nicht. Am besten mal mit der Suchfunktion nach malloc suchen (new hab ich im Programm bisher noch nicht verwendet) und überall checken, ob der Speicher auch wieder freigegeben wird.

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •