Datei einlesen Vereinfachen



  • Moin, Moin ihr leut,
    hab da ma ne frage.
    Ich habe ein kleines Programm geschrieben, welches daten in ein Array Speichert.
    Klappt auch alles wunderbar 🙂
    jetzt hab ich das programm erweitert, das ich den Inhalt des Arrays in eine Datei speichere. Klappt auch 😃
    Jetzt zum Öffnen der Datei 😡
    Quellcode:

    void __fastcall TMain_Frame::Oeffnen(TObject *Sender)
    {
    
    char zeile[MCHAR];
    AnsiString platz1;
    double platz2;
    int platz3;
    int i=0, x=0;
    
    istrstream eingabe (zeile,MCHAR);
    ifstream datei ("save.csv");
    
    if(datei)
    {
    datei.getline(zeile,MCHAR);
    eingabe.getline(zeile,MCHAR);
    
    while(!datei.eof())
    {
    Daten[i].nname="";
    Daten[i].vname="";
    x++;
            for(int j=0;j<=MCHAR; j++) //Vorname
            {
                    if(zeile[j] == ';')
                    {
                            for(int k=j+1; k<=MCHAR;k++) //Nachname
                            {
                                    if(zeile[k] == ';')
                                    {
                                            platz1="";
                                            for(int l=k+1;l<=MCHAR;l++) //Betriebszugehörigkeit
                                            {
                                                    if(zeile[l] == ';')
                                                    {
                                                            platz1="";
                                                            for(int m=l+1;m<=MCHAR;m++) //Gehalt
                                                            {
                                                                    if(zeile[m] == ';') break; //Abbruch für m-Schleife
                                                                    else {
                                                                            platz1 = platz1+ zeile[m];
                                                                            Daten[i].ggehalt = StrToFloat(platz1);
                                                                         }
                                                            } break; //Abbruch für l-Schleife
                                                    } else { platz1 = platz1 + zeile[l];
                                                             Daten[i].zeit = StrToInt(platz1); }
                                            } break; //Abbruch für k-Schleife
                                    } else Daten[i].nname = Daten[i].nname + zeile[k];
                            } break; //Abbruch für j-Schleife
                    } else Daten[i].vname = Daten[i].vname + zeile[j];
            }
    datei.getline(zeile, MCHAR);
    fkt_berechnen(i, false);
    i++;}
    datei.close(); }
    Main_Frame->ScrollBar1->Position=2;
    Main_Frame->ScrollBar1->Position=1;
    }
    

    geht das auch einfacher... 😕

    Die Datensätze sind immer durch ein Semikolon (;) getrennt.

    Danke, MFG ARO



  • Ein Ansatz mit TStringList:

    // Beispielzeile aus datei.csv
      // Name;Vorname;Alter
      String Daten[3][100];
    
      TStringList *list = new TStringList();
      list->LoadFromFile("datei.csv");
      TStringList *line = new TStringList();
      line->Delimiter = ';';
      for (int y = 0; y < list->Count; y++)     // Zeilen abklappern
      {
        line->DelimitedText = list->Strings[y]; // aktuelle Zeile einlesen
        for (int x = 0; x < line->Count; x++)   
          Daten[x][y] = line->Strings[x];          // Zeile aufsplitten
      }
      delete line;
      delete list;
    

    DelimitedText und Delimiter gibt es allerdings erst ab BCB6. In früheren Versionen liesse sich CommaText verwenden, das ist aber, da auf Kommas als Trennzeichen beschränkt, nicht ganz so elagant einzusetzen.



  • Hallo,

    Eine Alternative wäre die Verwendung von std::string statt char* oder AnsiString. Hier gibt es z.Bsp die Funktion find und substr.
    Also

    string zeile;
    ifstream datei ("save.csv");
    
    if(datei)
    {
    getline(datei,zeile); // Zeile einlesen
    
    while(!datei.eof())
    {
       size_t pos = zeile.find(0,";"); // erstes ; suchen und Position zurückgeben
       if( pos != string::npos ) // Zeichen gefunden ?
       {
           string first = zeile.substr(0,pos-1);
           size_t pos2 = zeile.find(pos+1,";"); // zweites; suchen und Position zurückgeben
           if( pos2 != string::npos ) // Zeichen gefunden ?
           {
               string first = zeile.substr(pos+1,pos2-1);
    // usw.
           }
        }
    }
    

    Dies ist natürlich nicht vollständig. Du mußt das noch anpassen.
    Man könnte natürlich auch eine Funktion schreiben, die einen gegebenen String an Semikolons aufteilt.
    Hier mal ein Beispiel

    int DivideString(const string &src, vector<string> &res, char delim)
    {
      res.clear();
      if( src.empty() ) return 0;
      vector<string::size_type> posvect;
      string::size_type pos(0);
      while( (pos = src.find(delim,pos)) != string::npos )
      {
           posvect.push_back(pos);
           pos++;
      }
      if( posvect.size() == 0)
      {
          res.push_back(src);
          return 1;
      }
      if( posvect[0] == 0 ) res.push_back("");
      else res.push_back(src.substr(0,posvect[0]));
      for( vector<string::size_type>::iterator it = posvect.begin() ; it != posvect.end()-1; ++it)
      {
           if( *it+1 == *(it+1)) res.push_back("");
           else res.push_back(src.substr(*it+1, *(it+1) - *it - 1));
      }
      res.push_back(src.substr(posvect.back()+1, src.length() - posvect.back()));
      return res.size();
    }
    

    Bei dir würde in delim ';' stehen und dann in res die Einzelstrings.

    Ciao



  • ABA, kann mir mal jemand erklären, wofür die einzelnen Zeilen sind?

    Haputschächlich

    TStringList *list = new TStringList();
      list->LoadFromFile("save.csv");
      TStringList *line = new TStringList();
      line->Delimiter = ';';
    

    die zweite und die letzte Zeile kann ich mir ja noch erklaeren, aber die andern Beiden Zeilen leider nicht. 😕

    Bitte um hilfe... 🙂

    MFG ARO



  • Da werden Instanzen der Klasse TStringList erstellt und entsprechend Speicher reserviert. In eine Liste wird die komplette Datei geladen, die andere dient als Puffer für die einzelnen Zeilen.


Anmelden zum Antworten