dynamisches mehrdimensionales char-Array



  • Liebe Gemeinde,

    ich bin noch ein ziemlicher Anfänger, was C++ betrifft und gerade am verzweifeln, was das parsen einer Datei angeht. Ich hab auch einiges gelesen, was das dynamische anlegen von Arrays angeht, habe aber leider Probleme, dies auf den Datentyp char zu übertragen.

    Hintergrund ist eine Textdatei mit folgenden Inhalt:

    kat1:inhalt kategorie 1
    kat2:der inhalt für die zwei!
    ...

    Die Anzahl der Zeilen ist unbekannt bzw. kann von Datei zu Datei variieren.

    Mein Anliegen ist nun, die einzelnen Zeilen in zwei Arrays zu speichern:

    arr_kat = {"kat1", "kat2"}
    arr_inhalt = {"inhalt kategorie 1", "inhalt für die zwei!"}
    

    Ich bekomme es aber zum verrecken nicht hin erstmal das array für die Kategorien anzulegen. Es wird zwar kompiliert aber beim ausführen bekomme ich entweder eine mir kryptische Fehlermelduhng, die, nicht lachen wenn ich was falsches schreibe, wohl Speicheradressen auflistet bzw. eine Endlosschleife.

    Ich bin unter Linux am werkeln und benutze den g++ der Version 4.4.1

    Ich bin für jeden Hinweis dankbar, der mir den Weg in die richtige Richtung weist!

    Anbei mein Code:

    #include <string>
    #include <iostream>
    #include <stdlib.h>
    #include <cstring>
    #include <fstream>
    
    using namespace std;
    
    int main() {
    
        char puffer[400];
        char zeichen;
        int zaehler;
        int k_index = 0;
    
        char **kat = new char*[5];
    
        ifstream datei;
        datei.open("dummy.txt");
    
        while(!datei.eof()) {
    
            datei.get(zeichen);
    
            if (datei.eof()) break;
    
            switch (zeichen) {
    
                case ':':
    
                    puffer[zaehler] = '\0';
                    cout << "p => " << puffer << endl;
    
                    kat[k_index] = puffer;
    
                    k_index++;
    
                    zaehler = 0;
    
                break;
    
                case '\n':
    
    // hier var inhalt füllen
    
    cout << "*" << endl;
                    zaehler = 0;
    
                break;
    
                default:
    
                    puffer[zaehler] = zeichen;
                    zaehler++;
    
                break;
    
            } // ende switch
    
        } // ende while()
    
        return 0;
    
    }
    


  • Benutze den Datentyp std::vector.



  • Danke Dir, das macht sicher Sinn!!!

    Bin mir aber nicht sicher, ob das die Lösung für die Aufgabenstellung ist, da wir diese Klasse noch nicht besprochen haben.

    Gibt's nichts für den "steinigen Weg", quasi from the scratch 😉

    Ich schätze, dass selbst in der Variablendeklaration ein Fehler ist, den ich gerne verstehen will.



  • cpp_padawan schrieb:

    Gibt's nichts für den "steinigen Weg", quasi from the scratch 😉

    Du wirst noch früh genug verstehen, wie vector funktioniert. Es gibt keinen Grund, den als Anfänger nachzuahmen.



  • In deinem Lösungsansatz sind mehrere Fehler:

    1. Kuck dir nochmal das erzeugen mehrdimensionaler Arrays mit new an
    2. strcpy() ist das was du suchst buffer[index] = puffer kopiert die Speicheradresse


  • Frohen Feiertag zusammen!

    Die Verwendung der Methode strcpy() funktioniert leider nicht. Führe ich das Programm aus, bekomme ich ein 'Segmentation fault', was wohl ein Indiz für ein Speicherzugriffsfehler ist.

    Somit kommen wir nochmal zum Verwenden von 'new'.

    ich initialisiere ein char Array, da ich aber nocht nicht weiss, wieviele Elemente gespeichert werden, lasse ich die Anzahl weg:

    char **kat = new char*;
    

    Wenn ich jetzt in einer for-Schleife die Elemente füllen will, funktioniert es auch anstandslos:

    for (int i = 0; i < 5; i++) {
    
        kat[i] = "abc";
        // strcpy(kat[i], "abc");
    
    }
    
    for (int i = 0; i < 5; i++) {
    
        cout << "i: " << i << " k: " << kat[i] << endl; 
    
    }
    

    Sobald ich die Elemente der Datei einlesen will, funktioniert nichts mehr.

    Bei der Verwendung von strcpy() bekomme ich bei Ausführung ein Segmentation fault, wie oben erwähnt, wenn ich den puffer einfach in kat[k_index] kopieren will, bekomme ich folgenden Fehler bei Ausführung des Programms:

    *** glibc detected *** ./test: free(): invalid pointer: 0xbfd4af64 ***
    ======= Backtrace: =========
    /lib/tls/i686/cmov/libc.so.6[0x3d9ff1]
    /lib/tls/i686/cmov/libc.so.6[0x3db6f2]
    /lib/tls/i686/cmov/libc.so.6(cfree+0x6d)[0x3de7cd]
    /lib/tls/i686/cmov/libc.so.6(_IO_free_backup_area+0x34)[0x3d84d4]
    /lib/tls/i686/cmov/libc.so.6(_IO_unsave_markers+0x32)[0x3d81f2]
    /lib/tls/i686/cmov/libc.so.6(_IO_file_close_it+0x42)[0x3d6fe2]
    /lib/tls/i686/cmov/libc.so.6(fclose+0x188)[0x3ca548]
    /usr/lib/libstdc++.so.6(_ZNSt12__basic_fileIcE5closeEv+0x5d)[0x90964d]
    /usr/lib/libstdc++.so.6(_ZNSt13basic_filebufIcSt11char_traitsIcEE5closeEv+0xa4)[0x8b8474]
    /usr/lib/libstdc++.so.6(_ZNSt14basic_ifstreamIcSt11char_traitsIcEE5closeEv+0x25)[0x8ba3c5]
    ./test[0x8048bcf]
    /lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe6)[0x385b56]
    ./test[0x8048991]
    ======= Memory map: ========
    001d3000-001d4000 r-xp 00000000 00:00 0          [vdso]
    0036f000-004ad000 r-xp 00000000 08:11 176013     /lib/tls/i686/cmov/libc-2.10.1.so
    004ad000-004ae000 ---p 0013e000 08:11 176013     /lib/tls/i686/cmov/libc-2.10.1.so
    004ae000-004b0000 r--p 0013e000 08:11 176013     /lib/tls/i686/cmov/libc-2.10.1.so
    004b0000-004b1000 rw-p 00140000 08:11 176013     /lib/tls/i686/cmov/libc-2.10.1.so
    004b1000-004b4000 rw-p 00000000 00:00 0 
    00852000-00938000 r-xp 00000000 08:11 1709       /usr/lib/libstdc++.so.6.0.13
    00938000-0093c000 r--p 000e6000 08:11 1709       /usr/lib/libstdc++.so.6.0.13
    0093c000-0093d000 rw-p 000ea000 08:11 1709       /usr/lib/libstdc++.so.6.0.13
    0093d000-00944000 rw-p 00000000 00:00 0 
    009ef000-00a0a000 r-xp 00000000 08:11 64         /lib/ld-2.10.1.so
    00a0a000-00a0b000 r--p 0001a000 08:11 64         /lib/ld-2.10.1.so
    00a0b000-00a0c000 rw-p 0001b000 08:11 64         /lib/ld-2.10.1.so
    00c74000-00c98000 r-xp 00000000 08:11 176017     /lib/tls/i686/cmov/libm-2.10.1.so
    00c98000-00c99000 r--p 00023000 08:11 176017     /lib/tls/i686/cmov/libm-2.10.1.so
    00c99000-00c9a000 rw-p 00024000 08:11 176017     /lib/tls/i686/cmov/libm-2.10.1.so
    00f6c000-00f88000 r-xp 00000000 08:11 2752       /lib/libgcc_s.so.1
    00f88000-00f89000 r--p 0001b000 08:11 2752       /lib/libgcc_s.so.1
    00f89000-00f8a000 rw-p 0001c000 08:11 2752       /lib/libgcc_s.so.1
    08048000-08049000 r-xp 00000000 08:11 2630472    /home/atze/Desktop/cpp_test/test
    08049000-0804a000 r--p 00000000 08:11 2630472    /home/atze/Desktop/cpp_test/test
    0804a000-0804b000 rw-p 00001000 08:11 2630472    /home/atze/Desktop/cpp_test/test
    09e5d000-09e7e000 rw-p 00000000 00:00 0          [heap]
    b7700000-b7721000 rw-p 00000000 00:00 0 
    b7721000-b7800000 ---p 00000000 00:00 0 
    b78d6000-b78d9000 rw-p 00000000 00:00 0 
    b78ed000-b78ef000 rw-p 00000000 00:00 0 
    bfd38000-bfd4d000 rw-p 00000000 00:00 0          [stack]
    Aborted
    atze@Tron:~/Desktop/cpp_test$
    

    Hier mal mein jetziger Stand:

    #include <string>
    #include <iostream>
    #include <stdlib.h>
    #include <cstring>
    #include <fstream>
    
    using namespace std;
    
    int main() {
    
        char puffer[400];
        char zeichen;
        int zaehler = 0;
        int k_index = 0;
    
        char **kat = new char*;
    
        ifstream datei;
        datei.open("dummy.txt");
    
        while(!datei.eof()) {
    
            datei.get(zeichen);
    
            if (datei.eof()) break;
    
            switch (zeichen) {
    
                case ':':
    
                    puffer[zaehler] = '\0';
                    cout << "p => " << puffer << endl;
    
                    kat[k_index] = puffer; // oder strcpy();
                    // strcpy(kat[k_index], puffer);
    
                    k_index++;
    
                    zaehler = 0;
    
                break;
    
                case '\n':
    
                    // inhalt wird hier gefuellt
                    cout << "*" << endl;
                    zaehler = 0;
    
                break;
    
                default:
    
                    puffer[zaehler] = zeichen;
                    zaehler++;
    
                break;
    
            } // ende switch
    
        } // ende while()
    
        // cout << "<<<< " << dateiname << " SCHLIESSEN >>>>" << endl;
        cout << "<<<< dummy.txt SCHLIESSEN >>>>" << endl;
        datei.close();
    
        /*
        for (int i = 0; i < 5; i++) {
    
            kat[i] = "abc";
            // strcpy(kat[i], "abc");
    
        }
    
        for (int i = 0; i < 5; i++) {
    
            cout << "i: " << i << " k: " << kat[i] << endl; 
            // strcpy(kat[i], "abc");
    
        }
        */
    
        return 0;
    
    }
    

    Danke schonmal für die Mühe!



  • cpp_padawan schrieb:

    ich initialisiere ein char Array, da ich aber nocht nicht weiss, wieviele Elemente gespeichert werden, lasse ich die Anzahl weg:

    char **kat = new char*;
    

    Das geht so nicht. new kann nicht zaubern und die benötigte Anzahl Elemente vorhersehen. Mit new char* forderst du einen einzelnen char* an, das ist natürlich zu wenig.

    Wenn du Magie willst, nimm std::vector<std::string> . 😉
    Dort kannst du ohne Weiteres erst im Nachhinein Elemente hinzufügen und musst dich kein bisschen um die Speicherverwaltung kümmern.


Anmelden zum Antworten