Char grenzen



  • Guten Tag

    Ich habe wieder einmal ein Thema bei dem mich die meisten wahrscheinlich am liebsten mit einem Baseballschläger... egal...

    Ich habe den Auftrag eine Textdatei einzulesen und dann weiter zu verarbeiten. Funktioniert soweit auch ganz gut. Ich speichere Zeile für Zeile in ein Char Array und verarbeite sie von dort aus Buchstabe für Buchstabe weiter. Nun ist das Problem dass die Textdatei ziemlich gross werden kann. Die längste die ich bisher gefunden habe hatte 389'721 Zeilen. Wenn ich aber das Array schon "nur" auf [50000][1024] einstelle stürzt der das ganze Programm ab und startet neu. Kann mir jemand helfen oder eine alternative nennen?

    Programm: Borland C++ Builder 6



  • indem du nicht alles auf einmal in dein array einliest sondern Zeile für Zeile immer in das selbe Array (oder besser noch einen geeigneten Container) liest und dann sofort verarbeitest.



  • Die Textdatei muss aber zuerst angezeigt werden und vom User abfragen was er abändern soll... so einfach verschnibbeln geht leider nicht...



  • legst Du das array zufällig so an:

    char array[50000][1024];
    

    Wenn ja, dann Schlag mal den Begriff Stacksize nach 😉



  • Ich hoffe doch dass es dynamisch angelegt wird, oder nicht? Sonst ist das Array für die meisten Dateien viel zu groß, für einige zu kleine, aber für kaum eine in der richtigen Größe...



  • loks schrieb:

    Wenn ja, dann Schlag mal den Begriff Stacksize nach 😉

    Habe unter Optionen die Stacksize gefunden und abgeändert. Aus irgendeinem Grund funktioniert es aber trotzdem nicht...

    pumuckl schrieb:

    Ich hoffe doch dass es dynamisch angelegt wird, oder nicht? Sonst ist das Array für die meisten Dateien viel zu groß, für einige zu kleine, aber für kaum eine in der richtigen Größe...

    Bei dynamischen char funktioniert das Programm nicht mer wirklich... vielleicht mache ich was falsch, aber so falsch kann es nicht sein wenn er das Programm trotzdem kompiliert...

    Habe es versucht mit

    char ** bsp;
    

    Das habe ich in irgendeinem Forum mal aufgeschnappt…



  • spricht irgendwas gegen std::vector< std::string > ?

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>
    
    std::vector<std::string> get_data_from_file(const char* file_name)
    {
      std::ifstream file(file_name);
      if(! file.good())
    	  throw 0; //TODO
    
      std::vector<std::string> R;
    
      for(std::string to_add; std::getline(file, to_add); )
      {
        R.push_back(to_add);
      }
    
      return R;
    }
    
    int main()
    {
      std::string dateiname;
      std::cout << "Dateiname?" << std::endl;
      std::cin >> dateiname;
    
      std::vector<std::string> content = get_data_from_file(dateiname.c_str());
    }
    

    ungetestet

    bb

    PS: Bei deinem Versuch fehlt ein paar Mal new[] ... und dann am ende auch die delete[] s



  • Habe unter Optionen die Stacksize gefunden und abgeändert.

    Das ist keine Loesung. Benutze einfach new und delete!

    spricht irgendwas gegen std::vector< std::string >

    Spricht was dagegen, die Textdatei als einzigen String zu behandeln?

    aber so falsch kann es nicht sein wenn er das Programm trotzdem kompiliert

    Der ist gut. Ich kann viel Mist produzieren, der trotzdem kompiliert.

    Das habe ich in irgendeinem Forum mal aufgeschnappt…

    Ausprobieren, Frickeln oder Aufschnappen ist kein gangbarer Weg, um programmieren zu lernen.



  • knivil schrieb:

    spricht irgendwas gegen std::vector< std::string >

    Spricht was dagegen, die Textdatei als einzigen String zu behandeln?

    gewohnheit^^ und das die einzige methode, die wirklich unformatiert ausgeben kann get(char &s) ist (oder liegt das nur an meinem unwissen?^^) und ich nicht weiß, ob es wirklich performant ist, jedes zeichen einzeln zu lesen...
    dann kommt noch hinzu, dass std::ifstream::pos_type nicht zu gebrauchen ist... somit ist das mit dem reserve auch bissl doof...
    ansonsten eigtl wirklich nichts...

    im endeffekt müsste er vll mal sagen, was er wirklich machen will^^

    std::string get_data_from_file(const char* file_name)
    {
      std::ifstream file(file_name);
      if(! file.good())
        throw 0; //TODO
    
      std::string R;
      for(char to_add; file.get(to_add); )
      {
        R.push_back(to_add);
      }
    
      return R;
    }
    

    und muss eben paar mal umkopieren - oder hab ich da ne möglichkeit übersehen, wie man doch an ne länge kommt, mit der man auch was anfangen kann? ^^

    bb



  • Ich halte es nicht für nötig das Programm weiter zu erklären, das würde alles nur komplizierter machen. Ich möchte einfach nur eine txt File einlesen und diese so zwischenspeichern, dass ich Zeichen für Zeichen überprüfen kann. Für die Verarbeitung und Ausgabe ist es nötig, dass die ganze File geladen wird.

    Ist es nicht einfach möglich die Begrenzung zu erhöhen? das mit dem Stacksize hatte mir schon hoffnung gemacht 🙂



  • Mathiable schrieb:

    Ist es nicht einfach möglich die Begrenzung zu erhöhen?

    nein - und selbst wenn es mit dieser option gehen würde, kannst du es in die tonne treten...
    warum nimmst du nicht einen der von mir geposteten ansätze?

    Mathiable schrieb:

    Ich halte es nicht für nötig das Programm weiter zu erklären, das würde alles nur komplizierter machen

    Du sollst nicht das Programm erklären sondern wozu du den Inhalt der Datei brauchst - wenn du das nicht tust, können wir dir auch keinen guten Rat geben sondern nur einen Standard-Rat...

    bb



  • Mathiable schrieb:

    Ich möchte einfach nur eine txt File einlesen und diese so zwischenspeichern, dass ich Zeichen für Zeichen überprüfen kann. Für die Verarbeitung und Ausgabe ist es nötig, dass die ganze File geladen wird.

    Du kannst doch mittels der vorgeschlagenen Lösungen jeden Buchstaben einzeln überprüfen. Nur, dass du die Zeichen eben nicht direkt beim Einlesen prüfst sondern erst, nachdem die ganze Datei in ein std::vector< std::string > - Objekt eingelesen wurde.

    Das was du wilst, wird in dem meisten Fällen irgendein olles Ansi-C-Gefrickel. Das was die anderen dir hier angeboten haben, liefert sauberen C++-Code mit schönen STL-Komponenten 😉



  • #include <vector>
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
       vector<char> Buffer;
       ifstream ifs( "c:/test.txt" );
    
       if( ifs.good() )
       {
          ifs.seekg( 0, ios::end );
          Buffer.resize( ifs.tellg() );
          ifs.seekg( 0, ios::beg );
    
          if( false == Buffer.empty() )
          {
             ifs.read( &Buffer[0], Buffer.size() );
          }
       }
    }
    


  • DocShoe schrieb:

    std::vector<char> Buffer(ifs.tellg());

    ah - ok... mit vector funktioniert das reserve - bei string nicht 😣
    std::string Buffer(ifs.tellg());
    will zumindest der msvc nicht haben...

    bb



  • Ich habe keine Probleme mit dem einlesen, ich mache einfach <file>.getline(); Ich überprüfe die Datei auch erst nachdem sie geladen ist. Das mit den Vektoren sieht für mich einfach noch ein bisschen aus wie Spanisch. 🙂

    Gut, ich hab jetzt immerhin einen Ansatz. Ich informier mich mal über Vektoren und melde mich wieder wenn ich nicht weiter komme.

    Und danke für die Geduld 😉



  • je nachdem, ob zeilenumbrüche interessant sind oder nicht kannst du das mit dem vector auch weglassen:

    std::string get_data_from_file(const char* file_name)
    {
      std::ifstream file(file_name);
      if(! file.good())
        throw 0; //TODO
      file.seekg(std::ios_base::end);
      std::vector<char>(file.tellg());
      file.sekkg(std::ios_base::begin);
      for(char to_add; file.get(to_add); )
      {
        R.push_back(to_add);
      }
    
      return std::string(R.begin(), R.end());
    }
    

    zu vector und anderen containern gibts nen guten artikel:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-143816.html

    sehr oft reicht auch die doku schon, um zu verstehen, wie was geht:
    http://www.cplusplus.com/reference/

    bb



  • unskilled schrieb:

    gewohnheit^^ und das die einzige methode, die wirklich unformatiert ausgeben kann get(char &s) ist (oder liegt das nur an meinem unwissen?^^) und ich nicht weiß, ob es wirklich performant ist, jedes zeichen einzeln zu lesen...

    Warum das? Es handelt sich doch um eine Textdatei, also ist getline(inputstream, string, EOF) doch praktisch. Danach kann er mit dem String und jedem Zeichen machen, was er will.

    Und zu deinem unformatiert: oeffne die Datei einfach im Binaermodus lese sie mittels read ein.



  • So, noch einfacher geht´s glaube ich nicht mehr...

    #include <vector>
    #include <iostream>
    #include <fstream>
    #include <iterator>
    
    using namespace std;
    
    int main()
    {
       ifstream ifs( "c:/test.txt" );
    
       // wird von meinem Compiler als lokale Funktionsdeklaration erkannt, geht
       // also leider nicht.
       // vector<char> Buffer( istream_iterator<char>( ifs ), 
       //                      istream_iterator<char>() );
    
       vector<char> Buffer;
       Buffer.assign( istream_iterator<char>( ifs ), istream_iterator<char>() );
    }
    

    Wenn man drei Mal char durch string ersetzt bekommt man die Datei wortweise.


Log in to reply