Array mithilfe von getline() füllen



  • Ich rate mal:

    1. frage ist ein char-array
    2. alle ist ein array von char-Pointern (also char* alle[])

    Dann sorgst du mit deiner Zuweisung in der Schleife dafür, dass jeder Eintrag von "alle" auf den C-String in frage zeigt - und damit egal was du asugibst immer die selbe ausgabe ist (weil ja alle auf den selben C-String zeigen).

    Tip: benute für frage einen std::string, dann gibts keine Größenbeschränkung beim getline(), und benutze für alle einen Container von strings statt eines normalen Arrays, dann gibts keine vorgegebene Größe für die Datei und dein Problem verschwindet auch gleich.



  • Danke, pumuckl, ich habe jetzt ziemlich lange im Internet nach einer Alternative mit Strings bzw. vector recherchiert und hab versucht, den Prozess des Herauslesens so kurz wie möglich zu machen, aber es funktioniert einfach nicht, weil ich ne runtime error bekomme (string subscript out of range).

    #include <string>
    #include <vector>
    #include <iostream>
    #include <fstream>
    #include <cstdio>
    using namespace std;
    
    int main()
    {
    	fstream quesFile;
    	quesFile.open("E:\\C++\\Microsoft Visual Studio 9.0\\MyProjects\\Quizzle\\Quizzle\\fragen.txt", ios::in);
    	vector<string> line;
    	string inhalt;
    	quesFile.seekg (0, ios::beg);
        do
        {
    		getline(quesFile,inhalt);
    		line.push_back(inhalt);
        }
    	while (!quesFile.eof());
    	cout << "5. Array: " << inhalt[4] << endl;
    	cin.get();
    	quesFile.close();
    	return 0;
    }
    


  • Du machst einmal zu oft push_back(). Denn eof wird erst beim nächsten Leseversuch nach Erreichen des Dateiendes gesetzt.

    Und überprüf erst mal, ob die Größe deines Vektors mindestns 5 ist, bevor du auf das fünfte Element zugreifst.



  • Ich weiss Eure Hilfe wirklich zu schätzen aber könnte jemand mir bitte sagen, nicht nur was ich falsch mache, sondern auch wie man's richtig macht? um das Problem mit der Länge des Vektors zu umgehen, habe ich die for-Schleife eingebaut. Wenn ich das richtig verstanden habe, Michael, dann kommt das pushback nach do-while? würde also so aussehen:

    [...]
    	quesFile.seekg (0, ios::beg);
        do
        {
    		getline(quesFile,inhalt);
        }
    	while (!quesFile.eof());
    	line.push_back(inhalt);
    	for (unsigned int i = 0; i < inhalt.size(); i++) cout << "5. Array: " << inhalt[i] << endl;
    	cin.get();
    [...]
    

    und folgenden Output produzieren, was eigentlich nur die Zeichen in der letzten Zeile sind:

    5. Array: 2
    5. Array: 0
    5. Array:
    5. Array: -
    5. Array: -
    5. Array: -
    5. Array: i
    5. Array: n
    5. Array: h
    5. Array: a
    5. Array: l
    5. Array: t
    5. Array: -
    5. Array: -
    5. Array: -
    

    Da kommt zwar keine fehlermeldung, aber das ist nicht das, was ich haben möchte.



  • Nein, so verwirfst du ja alle Zeilen und nur für die letzte rufst du push_back auf.

    Eher so:

    fstream quesFile("E:\\C++\\Microsoft Visual Studio 9.0\\MyProjects\\Quizzle\\Quizzle\\fragen.txt", ios::in);  // spar dir den Aufruf von open()
        vector<string> line;
        string inhalt;
        // quesFile.seekg (0, ios::beg);  überflüssig
        while(getline(quesFile, inhalt))
            line.push_back(inhalt);
    


  • [Rewind] schrieb:

    Wenn ich das richtig verstanden habe, Michael, dann kommt das pushback nach do-while?

    Nein, das hast du falsch verstanden. Das push_back muss schon in die Schleife, aber eben nur wenn der vorangegangene Leseversuch erfolgreich war. ich würds so machen:

    vector<string> fileContent; //
      string line;
      ifstream questionFile("E:\\C++\\Microsoft Visual Studio 9.0\\MyProjects\\Quizzle\\Quizzle\\fragen.txt");  
    
      getline(questionFile, line);
      while (!questionFile.eof())
      {
        fileContent.push_back(line);
        getline(questionFile, line);
      }
    

    ich hab die Variablen mal etwas umbenannt, weil du 4 Unschönheiten drin hattest:
    - deutsche und englische Namen gemischt verwirren nur
    - aussagenlose Variablennamen (inhalt? wessen inhalt?) machen den Code weniger klar als er sein könnte
    - falsche Variablennamen (der vector enthält alle Zeilen der datei, sollte also nicht line heißen) sind irreführend und verwirren unnötig
    - Abkürzungen (quesFile) machen den Code nur unnötig "holprig" zu lesen - und den Tippaufwand nimmt dir deine IDE bei Namensvervollständigung eh ab, egal obs 8 oder 15 Zeichen sind. Niemand liest gern "mkNewPtr2prvRefObj"



  • nur aus reiner neugier:
    geht das nich iwie (eleganter) mit std-mitteln? ^^

    ich hab jz aber auf die schnelle nichts hinbekommen - kanidaten wären zwar imho std::istream_iterator und std::back_inserter , aber kein Plan - ich hab nichts zu Stande bekommen : D

    bb





  • ty : >



  • Ok, ich habe es endlich zum Laufen gebracht und es funktioniert einwandfrei. Vielen Dank, unskilled, dein Vorschlag hat prima funktioniert. Die Variante von pumuckl spuckte bei mir nur einzelne Zeichen der letzten Zeile aus (der Fehler kann auch bei meiner Umsetzung liegen, aber ich bezweifle's). Und danke pumuckl für die Tipps. Ich werd versuchen, sie im Kopf zu behalten, wenn ich nächstes Mal um deine Hilfe bitte 🙂



  • [Rewind] schrieb:

    Die Variante von pumuckl spuckte bei mir nur einzelne Zeichen der letzten Zeile aus (der Fehler kann auch bei meiner Umsetzung liegen, aber ich bezweifle's).

    Ich bezweifle es meinerseits 😉
    Du musst natürlich die Schleife mit dem output über den vector (fileContext) laufen lassen, nicht über den String (line) - im String ist nämlich am Ende tatsächlich nur die letzte Zeile enthalten, und dort mit der Schleife drüber zu laufen gibt dann tatsächlich nur einzelne Zeichen aus.



  • [Rewind] schrieb:

    Vielen Dank, unskilled, dein Vorschlag hat prima funktioniert.

    Danke für die Blumen - nur hab ich in dem ganzen thread genau 2 posts geschrieben - eine frage und einmal nen danke, weil jmd anderes die forensuche richtig bedienen kann : D

    bb


Anmelden zum Antworten