C++ Textdatei in 2-Dimensionalen Array einlesen



  • Hallo zusammen :),

    seit einem mehr oder weniger langen Zeitraum schlage ich mich mit dem Problem herum eine Textdatei vernünftig zeilenweise auslesen zu können. Ich habe zwar
    einen Code der halbwegs funktioniert, allerdings bin ich mit diesem noch überhauput nicht zufrieden
    Hier mal der Code:

    //include und bla
    vector<string> vec;
    //[...]
    
    while (getline(newfile, str2))
    vec.push_back(str2);
    vec.size();
    newfile.open(GetFileDirectory("\\scripts\\", chs + end).c_str(), ios::in); 
    cout << "Number of commands: " << vec.size() << endl;
    
    for (int u = 0; u < vec.size(); u++)
     {
    	newfile.getline(&lineN[u], sizeof(lineN));
    	cout << "\n\t - " << "(" << u << ") " << &lineN[u] << endl;        // Funktioniert super, gibt die Zeilen aus
     }
    
    cout<<&lineN[0]; //Funktioniert nicht richtig, gibt nur Bruchstücke aus der Datei aus oder falsch ergänzte Zeilen
    

    Nun möchte ich zum Beispiel, dass ich mir nach der For-Schleife die einzelnen Zeilen in beliebiger
    Reihenfolge ausgeben lassen kann, wenn ich nun aber lineN[0] versuch ausgeben zu lassen, kommen
    da irgendwie aneinander gereihte Teile aus der Datei zustande. Ich wäre ja schon mal froh wenn
    dafür jmd ne Lösung hat... Ich steh glaub irgendwie aufm Schlauch

    Als nächstes wollte ich dann, dass ich einen 2d array für das Auslesen der Datei, also
    das ich quasi noch die Zeichen einer Zeile einzeln anzeigen lassen kann.
    Bsp.: "test" soll durch array[zeile][zeichen] dann zum Beispiel die Ausgabe auf "t" begrenzen
    oder "te" oder "st", ich hoffe ihr versteht das in etwa.

    Vielen Dank für alle Antworten im Vorraus 👍
    ich hoffe ihr könnt mir helfen

    Gruß

    Cyax


  • Mod

    Hast du da mehrere Codes zusammen kopiert, ohne sie zu verstehen? Der Code macht zweimal das gleiche. Einmal in gut, einmal in ganz, ganz schlecht*. Dein Zeilenzaehlen ist dabei die gute Variante! Mal ein bisschen aufgeraeumt:

    vector<string> vec;
    {
      ifstream file(GetFileDirectory("\\scripts\\", chs + end)); // Wenn kein C++11: Hier noch .c_str() an den String anhaengen
      string str;
      while (getline(file, str))
        vec.push_back(str); 
    }
    // Zeilen stehen nun einzeln und vollstaendig in vec
    

    *: Oder anders gesagt: Falsch. Deshalb macht dein Programm auch nicht, was du dir wuenscht. Wo du das her kopiert hast, gehoert nie wieder angeschaut. Der Verfasser versuchte C in C++ zu machen (schon an sich eine schlechte Idee) und hat's nicht einmal richtig hinbekommen.



  • Ich verstehe leider nicht genau was so schlimm an dem Code ist.
    Das einzige was da übrig bleibt ist getline und die For-Schleife und was soll daran falsch sein? Naja, jedenfalls mal Danke für deine schnelle Antwort, werds gleich mal testen.


  • Mod

    Cyax schrieb:

    Ich verstehe leider nicht genau was so schlimm an dem Code ist.

    Zeilen 1-6 sind gut. Das sind die, die ich uebernommen habe. Danach wird's uebel:

    vec.size();
    

    Ja? Was soll das? Was macht dies deiner Meinung nach? Was auch immer du denkst, was es tut, was es in Wirklichkeit tut ist einfach: Gar nix.

    newfile.open(GetFileDirectory("\\scripts\\", chs + end).c_str(), ios::in);
    

    Ist denn die gleiche Datei nicht schon offen?

    for (int u = 0; u < vec.size(); u++)
    

    Du hast gerade die ganze Datei eingelesen. Und jetzt liest du sie wieder ein? Hast du gar nicht bemerkt, dass der andere Code die Datei einliest? Einfach blind irgendwo aus dem Internet kopiert zum zaehlen der Anzahl der Zeilen einer Datei? Warum musst du die Anzahl der Zeilen ueberhaupt im Voraus wissen Zwecks Einlesen? Der Code in Zeilen 1-6 musste das nicht.

    newfile.getline(&lineN[u], sizeof(lineN));
    

    lineN ist was fuer eine Art von Objekt? Ein 2D-char-Array? Dann ist lineN[u] ein char-Array. Warum dann der Adressoperator? Wenn lineN[u] ein char-Array ist, was hat sizeof(lineN) da zu suchen? Das ist doch die Gesamtgroesse des 2D-Arrays!
    Oder ist lineN irgendwas dynamisch alloziiertes? Schliesslich brauchtest du ja vorher anscheinend die Anzahl der Zeilen, daher habe ich diesen Verdacht. Dann waere das sizeof gleich doppelt falsch.
    Allgemein zu diesem getline: Was ist, wenn die Zeilen zu lang sind?
    In dieser Zeile liegen mit die Hauptgruende, warum du nur Muell bekommst. Selbst wenn man die anderen Fehler mal ignoriert. Hier ist einfach alles falsch.

    Hoechstwahrscheinlich ist lineN sogar ein ganz falscher Typ, denn viele der Konstrukte hier duerften gar nicht compilieren, wenn es sich um ein klassisches 2D-Array handeln wuerde. Ist das etwa ein char-Array oder ein Zeiger auf char? Dann wuerden die Konstrukte mit dem Adressoperator naemlich compiliere. Und ohne wuerden sie aus guten Gruenden nicht, weils einfach nur Bloedsinn waere, mehrere Zeichenketten im Platz fuer nur eine Zeichenkette abzuspeichern. Hast du einfach nur wild Zeichen in deinen Code eingefuegt, bis der Compiler nicht mehr gemeckert hat?



  • Ist denn die gleiche Datei nicht schon offen?

    Ja, ist jetzt logisch, lag daran das ich vorher noch damit rumprobiert habe,
    ist also unbeabsichtigt gewesen.

    Hast du gar nicht bemerkt, dass der andere Code die Datei einliest?

    Nein, nicht wirlich, ich habe da nicht drauf geachtet. Vor 1-2 Monaten hab ich hier im Forum gefragt, wie ich die Zahl der Zeilen auslesen könnte und als Antwort bekommen das vec.size dann quasi die Zahl der Zeilen angibt. Also falsch verstanden...

    Der Rest ist leider auch meinen Experimenten zum Opfer gefallen, ist noch ein älterer Code den ich in einem anderen Projekte gebraucht habe...

    Kannst du mir aber bitte sagen wie ich "schönen" Code schreiben kann, bzw. wie
    meiner besser wird? Ich finde da keinene richtigen Ansatz (also allgemein, nicht für dieses Beispiel).

    Gruß

    Cyax


  • Mod

    Cyax schrieb:

    Kannst du mir aber bitte sagen wie ich "schönen" Code schreiben kann, bzw. wie
    meiner besser wird? Ich finde da keinene richtigen Ansatz (also allgemein, nicht für dieses Beispiel).

    Eine schwere Frage, oder sehr leicht, je nachdem, wie man es sieht. Mal Hand aufs Herz: Du hast den Code nicht wirklich programmiert, sondern zusammen kopiert, bestenfalls noch ein paar Änderungen nach dem Prinzip "Versuch und Irrtum" vorgenommen. Wobei ein "Erfolg" bei diesem Rumprobieren schon war, wenn es überhaupt compilierte. Liege ich damit nahe an der Wahrheit? Falls ja, dann ist die Antwort einfach, aber die Schlussfolgerung ist für dich schwere Arbeit: Tu das nicht! Wenn du Code schreibst, dann musst du ihn auch verstehen. Und wenn du verstehst, was du tust, dann wird der Code auch automatisch besser. Dazu musst du die Sprache richtig beherrschen, etwas, wo es bei dir derzeit noch zu mangeln scheint. Denn durch Kopieren von Codefragmenten lernt man keine Sprache, sondern nur, wie man besser im Kopieren wird.
    Wenn du dann überhaupt erst einmal die Grundlagen von C++ kannst, dann kann man über "guten" C++-Stil reden. Idealerweise bringt dir ein gutes Lehrbuch gleich den guten Stil bei, so dass das dann nichts neues mehr ist. Leider gibt es sehr viele schlechte Bücher (und Lehrer!), besonders im deutschsprachigen Bereich, und Internettutorials kann man auch alle vergessen (außer zu fortgeschrittenen Themenbereichen). Daher gibt es hier im Forum Listen guter Bücher, guck zum Beispiel mal in meiner Signatur.



  • Ja ich gebs zu der Code war schlicht und einfach scheiße, kann mal vorkommen.
    Ich denke aber das ich C++ z.T. verstanden habe, aber das ein oder andere Kapitel muss ich wahrscheinlich noch wiederholen.
    Allerdings muss ich sagen das ich manchmal keine anderen Wege außer kopieren finde, so habe ich neulich nach einer Methode gesucht Dezimalzahlen in Binärcode
    umzuwandeln, mathematsich gesehen hab ichs verstanden, 2 minuten gegooglet wie ich das in C++ umsetzen kann und das hier bei stackoverflow gefunden:

    bitset<7>(ascii).to_string() ;
    

    Was gibts da jetzt noch großartig zu verstehen, ich kann ja schließlich nicht alles auswendig können, oder?
    Der Code aus meiner Frage war echt beschissen, merk ich selber, aber ich glaube ich habe auch schon ganz gute Sachen hinbekommen (OHNE KOPIEREN)...

    Danke für deine Antwort, hat gut getan mal wieder etwas Kritik in die Richtung zu bekommen.

    Viele Grüße und einen schönen Abend
    Cyax


  • Mod

    Das ist doch fast ein perfektes Beispiel für das, was ich angesprochen habe. Kennst du nun Bitset und weißt, wozu es eigentlich da ist? Vermutlich nicht, denn du hast nur abgeschrieben. Wüsstest du nun, wie man Code schreibt, der Zahlen im Hexadezimalsystem ausgibt? Vermutlich nicht, denn du hast nur abgeschrieben. Wüsstest du nun, wie man Code schreibt, der Zahlen in Zahlensystemen ausgibt, für die die Standardbibliothek keine fertige Lösung vorgibt, also zum Beispiel dem Dreiersystem? Vermutlich nicht, denn du hast nur abgeschrieben.



  • Ja richtig, dann gebe ich bei google einfach ein "c++ bitset" und sehe diese
    Seit: http://www.cplusplus.com/reference/bitset/bitset/bitset/
    Da steht alles notwendig drauf, wenn ichs mir durchlese habe ichs verstanden.
    Hab ich jetzt immer noch abeschrieben? Ja!
    Wie würdest du denn ein Problem angehen (z.B. jetzt das mit der Umwandlung von
    Dezimal in Binär oder Hex)?
    Ich könnte die mathematische Rechnung vom Papier übertragen und mit meinen C++ Kenntnissen umsetzen, aber wieso sollte ich das tun wenn es auch mit einer Zeile geht.

    --> Ich kann es ja letzendlich nur in dieser Reihenfolge lösen, solange ich Bitset nicht kenne werde ich googeln müssen und eine Lösung für das Problem finden und werde diese erst hinterher verstehen.

    Gruß

    Cyax

    PS: Vector habe ich verstanden, ich weiß was was bedeutet, ich weiß wozu es gut ist und habe den Zusammenhang verstanden. Aber ich habe doch quasi trotzdem wieder abgeschrieben, ich weiß nun halt, was ich bei einem neuen Projekt gleich am Anfang besser machen kann.


Anmelden zum Antworten