Frage zum Füllen eines Char-Arrays - habe einen Fehler



  • Hallo liebe Community,

    Momentan beschäftige ich mich mit c++, bin also noch Anfänger.
    ich möchte eine Textdatei auslesen, die Werte trennen und in einem Struct speichern. Das Auslesen klappt wunderbar und das Speichern der einzelnen Zeilen in einem String geht auch. Das Zerlegen des Strings klappt aber irgendwie nicht, sobald das Char-Array mehr als 26 Zeichen bekommt -> ein Heap wurde beschädigt.
    Jedoch sehe ich den fehler nicht wirklich. Vielleicht könnt ihr mir einen Tipp geben?

    #include <iostream>
    #include <string>
    #include <vector>
    #include <algorithm>
    using namespace std;
    
    void main(){
    
    	int i = 0;
    	vector<string> zeichen;
    	zeichen.resize(6);
    	zeichen[0] = "sjsjrtzjhngf";
    	zeichen[1] = "dfgjsfgj";
    	zeichen[2] = "gghsfjdjghkgdhkdghkdkhfgjfeudfjdfj"; // wenn mehr als 26 zeichen, wird ein fehler ausgeworfen - aber warum?
    	zeichen[3] = "gzgz";
    
    	char * stringchar = NULL;
    
    	while(i < 4){
    	int laenge = zeichen[i].size()+1;
    	stringchar = new char(laenge);
    	strcpy(stringchar, zeichen[i].c_str());
    	cout<<"stringchar :"<<stringchar<<endl;
    	i++;
    	}
    
    system("pause");	
    }
    

    Ich weiß, dass sich der Sinn dieses Codes nicht ergibt. Mir geht es jedoch nur um den Fehler, der Auftritt, wenn im Char-Array mehr als 26 Zeichen reinkommen sollen.



  • Dein eigentlicher Fehler liegt hier:

    stringchar = new char(laenge);
    

    Du willst

    stringchar = new char[laenge];
    

    Aber warum kopierst du von einem std::string ein Heapallokiertes Array? Insbesondere, da du ja std::vector und std::string kennst?



  • Hallo,

    Vielen lieben Dank - das war es gewesen.

    Die Textzeilen der Textdatei lese ich in den Vector ein - da ich nicht weiß, wieviele Zeilen die Textdatei enthält.
    Das Zerlegen der eingelesenen Textzeilen mache ich mit strtok. Aber strtok benötigt ein Char-Array, deswegen kopiere ich es.
    Ich denke, das ganze geht auch einfacher, aber ich lerne ja noch (quasi learning by doing) - und ich habe hier im Forum schon einiges durch lesen gelernt.

    Gruß
    STBase

    ps: gern kann ich heute Abend auch den ganzen Quellcode posten.



  • Vergiß das delete[] nicht...



  • Caligulaminus schrieb:

    Vergiß das delete[] nicht...

    Hallo,
    guter Hinweis. Danke.
    Gruß
    STBase


  • Mod

    stbase schrieb:

    Hallo,

    Vielen lieben Dank - das war es gewesen.

    Die Textzeilen der Textdatei lese ich in den Vector ein - da ich nicht weiß, wieviele Zeilen die Textdatei enthält.
    Das Zerlegen der eingelesenen Textzeilen mache ich mit strtok. Aber strtok benötigt ein Char-Array, deswegen kopiere ich es.
    Ich denke, das ganze geht auch einfacher, aber ich lerne ja noch (quasi learning by doing) - und ich habe hier im Forum schon einiges durch lesen gelernt.

    Gruß
    STBase

    ps: gern kann ich heute Abend auch den ganzen Quellcode posten.

    Leitfaden:
    - Benutzt du new für Arrays ist das fast immer falsch.
    - Benutzt du Funktionen aus cstring/string.h ist das fast immer falsch (hier hast du vergessen cstring einzubinden, obwohl du strcpy benutzt!)
    - Benutzt du char-Arrays für Zeichenketten ist das fast immer falsch
    - Das "fast immer" in diesen Aussagen ist als "immer" zu verstehen, außer du konstruierst mit Gewalt ein Gegenbeispiel, bei dem es vielleicht einen winzigkleinen Vorteil gibt.

    P.S.: void main ist immer falsch.



  • Tausche gerne ein "ungeschickt" gegen ein "falsch" 🤡


  • Mod

    Swordfish schrieb:

    Tausche gerne ein "ungeschickt" gegen ein "falsch" 🤡

    Technisch gesehen ja, aber so merkt er es sich hoffentlich besser 🙂 . Und void main ist falsch.



  • stbase schrieb:

    Aber strtok benötigt ein Char-Array, deswegen kopiere ich es.

    Nein, strtok benötigt einen Pointer auf ein char-Array, und da std::vector garantiert die Elemente intern in so einem Array verwaltet, darfst du strok gerne den Pointer auf das erste Element des vector übergeben: vec.data() (in C++11) bzw. &vec[0] in C++03. Das Einzige worauf du aufpassen musst ist, dass du auch den Nulldelimiter im vector hast.



  • Hallo,

    vielen Dank für die Antworten. Dadurch kommt man auf ganz neue Ideen.
    Ich werde mir mal die Vectoren genau ansehen und das ganze ohne den Umweg über das Char-Array zu lösen.

    Gruß
    STBase


  • Mod

    pumuckl schrieb:

    stbase schrieb:

    Aber strtok benötigt ein Char-Array, deswegen kopiere ich es.

    Nein, strtok benötigt einen Pointer auf ein char-Array, und da std::vector garantiert die Elemente intern in so einem Array verwaltet, darfst du strok gerne den Pointer auf das erste Element des vector übergeben: vec.data() (in C++11) bzw. &vec[0] in C++03. Das Einzige worauf du aufpassen musst ist, dass du auch den Nulldelimiter im vector hast.

    strtok verändert aber den Inhalt, data zeigt jedoch auf einen const-Bereich.

    Aber wieso strtok? std::string und die algorithms bieten auch alles was strtok kann.



  • Hallo,
    ich habe es jetzt doch etwas anders gelöst und es sieht irgendwie besser aus 🙂

    // string zerlegen
    		string Terminzeile = "Titel;Betreff;Ort";
    		istringstream tzeile(Terminzeile);
    		string ausgabe;
    		while(getline(tzeile, ausgabe, ';'))
    			{
    		    cout<<ausgabe<<endl;
    			}
    

    nun gut, man lernt ja noch... 🙂



  • SeppJ schrieb:

    strtok verändert aber den Inhalt, data zeigt jedoch auf einen const-Bereich.

    Nein, data ist so definiert:

    c++11 Standard N3242=11-0012 schrieb:

    // 23.3.6.4, data access
    T* data() noexcept;
    const T* data() const noexcept;


Anmelden zum Antworten