Eine bestimmte Zeile aus einer großen .txt auslesen



  • dot schrieb:

    . Vor allem sind Jumps an den Anfang der Datei dann wesentlich schneller als Jumps an Stellen weiter hinten.

    Ja, das hab ich mir auch schon überlegt. Ganze Datei einlesen, dann funktioniert es super, die Zeit/Speicher habe ich jetzt auch ausprobiert und das ist auch Ok.

    Danke für eure Hilfe



  • Wenn das ähnlich zu Assembler-Programmcode wird, dann gibt es aber nur sehr wenige Sprungziele. Und wenn nicht mit goto gesprungen wird, gehts sequenziell weiter zur Folgezeile. Dann müßte man fseek nur machen, wenn ein Sprung stattfindet. Bei 10000 Zeilen Code vielleicht nur 500 Sprungziele. Dann kannste auch nur die cachen.



  • Ja, ich werde nicht so viele Sprungbefehle brauchen, aber wichtig ist, das ich sie verwenden kann. Sonst lese ich normalerweise mit der nächsten Zeile weiter.



  • padreigh schrieb:

    ifstream datei("test.txt");
            string line;
    
            while( datei.good() )
            {          
                getline(datei,line,'\n');
                alles.push_back(line);
                // std::cout << alles.size() << std::endl;
            }
    

    Diese Konstruktion liest eine Zeile zu viel, wenn das letzte Zeichen der Datei ein '\n' ist. Was in der überschüssigen Zeile steht, ist nicht definiert und von der Implementierung von getline abhängig.

    Vor diesen while(good)-lese-verarbeite oder schlimmer while(!eof)-lese-verarbeite -Konstruktionen kann man nur warnen. Für das Einlesen gilt das, was bei jedem Funktionsaufruf gilt, der einen Fehler produzieren kann.
    ZUERST aufrufen(hier lesen) und DANACH prüfen, ob es gut gegangen ist - und nicht umgekehrt. Also wenn unbedingt mit while, dann

    ifstream datei("input.txt");
            string line;
            while( getline(datei,line,'\n') )
            {          
                alles.push_back(line);
                // std::cout << alles.size() << std::endl;
            }
    

    Gruß
    Werner



  • MGOS schrieb:

    Ja, ich werde nicht so viele Sprungbefehle brauchen, aber wichtig ist, das ich sie verwenden kann. Sonst lese ich normalerweise mit der nächsten Zeile weiter.

    Ich würde das in jedem Fall alles zunächst einlesen. Du musst schon sehr wenig Speicher in Deinem PC haben, bevor Du da ein Problem bekommst.
    Und wenn das so eine Art Interpreter werden soll, der ein Script abarbeitet, so würde ich mehrere Typen von Kommandos implementieren, die eine gemeinsame Basisklasse haben.

    Wie viele verschieden 'Codes' (wie GOTO) kommen denn vor?
    Ist das so eine Art 'Text Adventure'?
    hat jede Zeile ein Label/Nr vor dem 'Code' stehen?



  • Is wird ca. 80 verschiedene Befehl-Codes geben, von denen viele sehr ähnlich sind, deshalb werde ich diese auch splitten, damit es weniger Aufwand ist.

    Normalerweiße hat jeder Code eine Nummer davorstehen, aber da der Anwender die .txt bearbeiten darf und muss, können sich da Fehler einschleichen, die erst überprüft werden müssen.



  • dot schrieb:

    Wenn du Zeile 7861 willst, warum nicht einfach:

    std::ifstream file(filename);
      int n = 1;
      while (file && n < 7861)
        if (file.get() == '\n')
          ++n;
      std::string line;
      std::getline(file, line);
    

    Das dürfte aber die ineffizienteste Variante von allen sein, oder?
    Schließlich wird nur Zeichen für Zeichen gelesen und kein größerer Buffer verwendet.


  • Mod

    m,.m,. schrieb:

    Schließlich wird nur Zeichen für Zeichen gelesen und kein größerer Buffer verwendet.

    Eventuelle Buffer liegen viel tiefer als irgendwelche Einleseroutinen der Standardbibliothek.



  • SeppJ schrieb:

    m,.m,. schrieb:

    Schließlich wird nur Zeichen für Zeichen gelesen und kein größerer Buffer verwendet.

    Eventuelle Buffer liegen viel tiefer als irgendwelche Einleseroutinen der Standardbibliothek.

    Kann man das also auch in produktiven Code so realisieren? Zu meinen Lieblingsthema gehört die Netzwerkprogrammierung und hier ist es z.B. nicht sehr effizient, wenn man nur jeweils 1 Zeichen einliest. Deshalb wäre ich jetzt der Meinung gewesen, dass selbiges auch auf alle anderen IO-Operationen zutrifft.

    Ich gehe natürlich schon davon aus, dass zumindest std::ifstream selber puffert, aber das sind ja letztendlich Implementationsdetails auf die man genau genommen nicht vertrauen kann.


  • Mod

    m,.m,. schrieb:

    Kann man das also auch in produktiven Code so realisieren?

    Ehrlich gesagt: Nein. Habe es nämlich gerade ausprobiert und mich da wohl getäuscht. Zwischen istream::get und istream::read mit großen Blöcken liegen Welten.


Anmelden zum Antworten