• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

[C++] Zeile für Zeile aus Datei lesen (getline)

mr.twister

Neues Mitglied
Hey Leute,
ich habe gerade mit C++ begonnen und möchte die Patientenverwaltung die wir in der Schule (Delphi) geschrieben haben schreiben. Dabei habe ich folgendes Problem:

Die Daten der Personen werden aus einer Textdatei im XML-Format geladen. Dazu steht in jeder Zeile ein Attribut (z.B: <name>Bob</name>). Ich versuche nun die ganze Zeit Zeile für Zeile mit einer While Schleife und getline auszulesen aber ich bekomme immer eine Fehlermeldung und Windows sagt Programm musste beendet werden.
Hier der Code:

Code:
[COLOR=seagreen]#include <iostream>
#include <fstream>
#include <string>[/COLOR]
[COLOR=blue]using namespace[/COLOR] std[COLOR=red];[/COLOR]

string Load[COLOR=red]()[/COLOR]
[COLOR=red]{[/COLOR]
  string text[COLOR=red];[/COLOR]
  ifstream file[COLOR=red];[/COLOR]  [COLOR=silver]//Datei-Handle[/COLOR]
  file[COLOR=red].[/COLOR]open([COLOR=blue]"data.pv"[/COLOR][COLOR=red],[/COLOR] ios[COLOR=red]::[/COLOR]in)[COLOR=red];[/COLOR] [COLOR=silver]//Datei wird geöffnet[/COLOR]
  [COLOR=blue]while[/COLOR][COLOR=red](![/COLOR]file[COLOR=red].[/COLOR]eof[COLOR=red]())[/COLOR] [COLOR=silver]//Solange noch Daten vorhanden sind wird die Schleife ausgeführt[/COLOR]
 [COLOR=red] {[/COLOR]
      text [COLOR=red]= ' ';[/COLOR]
      getline[COLOR=red]([/COLOR]file[COLOR=red],[/COLOR] text[COLOR=red]);[/COLOR] [COLOR=silver]//Es wird jeweils eine Zeile ausgelesen[/COLOR]
      [COLOR=silver]//cout << text << endl;[/COLOR]
  [COLOR=red]}[/COLOR]
  datei[COLOR=red].[/COLOR]close[COLOR=red]();[/COLOR]
[COLOR=red]}[/COLOR]
Grüße mr.twister
 
Hi,
könnte es daran liegen, dass du am Ende
Code:
 datei.close();
statt
Code:
 file.close();
stehen hast?
Außerdem wird in deiner Schleife die Variable text immer wieder zurück auf ' ' gesetzt.

mfg michaelos
 
Nein, daran liegt es leider nicht. Im Queltext hieß es Datei, aber ich dachte ich nenne das in File um, hört sich besser an und da alles in Englisch ist, kann ich auch die Namen Englisch machen^^
 
Naja es stürtzt immer ab und Codeblock sagt mir Programm wurde mit Status -1073741819 beendet... Das hilft euch wahrscheinlich nicht wirklich weiter.
Wie würdet ihr eine Datei einlesen und Zeile für Zeile ausgeben?
Das Programm macht alles was ich will stürtzt halt bloß immer ab. Und ich weiß auch, dass das wegen getline ist, aber Codeblocks meckert beim compilieren nicht rum.
 
Deine Funktion ist mit Rückgabewert vom Typ string deklariert, gibt aber nichts zurück.

Zeige im Zweifel den tatsächlichen Code.
 
Das verstehe ich nicht. Ich Gebe doch in die String-Variable Text den Inhalt des Streams zurück oder?
Wo gibst du diese zurück? Ich sehe kein return

Ich hab' seit Ewigkeiten nichts mehr mit C gemacht, aber müßte das nicht schon einen Fehler beim kompilieren erzeugen?
 
Also, in der Form, wie der Code gezeigt wurde, läuft er bestimmt nicht. Ich bin da auch nicht unbedingt Experte, aber auch sowas wie eine main-Funktion müsste als Einsprungspunkt sicherlich vorhanden sein.

Zum Beispiel so:

Code:
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

void Load()
{
    string text;
    ifstream file; //Datei-Handle
    file.open("data.pv", ios::in); //Datei wird geöffnet
    
    // Solange noch Daten vorhanden sind wird die Schleife ausgeführt
    while (!file.eof()) {        
        getline(file, text); //Es wird jeweils eine Zeile ausgelesen
        cout << text << endl;
    }
    
    file.close();
} 

int main(int argc, char **argv)
{
    Load();
    return 0;
}

Kompiliert unter Linux mit:

Code:
$ g++ ./test.cpp

file_get_contents-Funktion, die ich neulich zusammengeschustert habe:

Code:
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int file_get_contents(std::string filePath, std::string &buffer)
{
    int ret = 0;
    
    std::ifstream myfile(filePath.c_str());
    std::string line = "";

    int i = 0;
    
    if (myfile.is_open()) {
        while (myfile.good()) {
            if (i > 0) {
                buffer += "\n";
            }
            ++i;
            std::getline(myfile, line);
            buffer += line;
        }
        myfile.close();
    } else {
        ret = 1;
    }

    return ret;
}

int main(int argc, char **argv)
{
    std::string buffer = "";
    
    int ret = file_get_contents("data.pv", buffer);
    
    if (ret > 0) {
        std::cout << "Error while reading from file" << endl;
        return ret;
    }
    
    std::cout << buffer;    
    
    return 0;
}
 
@mermshaus: Natürlich habe ich auch die main Funktion. Das stimmte alles schon so. Ich will halt Zeile für Zeile auslesen, um dann für eine Patientenverwaltung das Attribut (z.B. name aus <name>) zu bestimmen und es dann in einem Objekt was Patients heißt zu schreiben, um darauf später mit GetName oder ähnlich darauf zugeifen zu können.
 
@mermshaus: Natürlich habe ich auch die main Funktion. Das stimmte alles schon so.
Es ist müsig über irgendeinen Code zu spekulieren. Wenn du gekürzten Code zeigst, dann bitte auch ein lauffähiges Beispiel, weil so wie du uns es gezeigt hast, stimmte es eben nicht.
 
Ok, Tut mir Leid. Kommt jetzt bei meiner nächsten Frage.

Ich habe Versucht zwei Klassen zu definieren. Diese binde ich dann in meine main.cpp ein.
Lässt sich mal wieder alles kompilieren, aber wenn man das Progamm ausführt, dann spuckt die Comandozeile folgendes aus:

This application has requested the Runtime to terminate it in an unu
Please contact the application's support team for more information.

Ich habe gemerkt, dass wenn ich die nitalisierung von meinem Objekt rausnehme das Programm ganz normal läuft.
Hier der Code:

main.cpp
Code:
[COLOR=green]#include <iostream>
#include <fstream>
#include <string>
#include "uPatients.h"[/COLOR]
[COLOR=blue]using namespace[/COLOR] std[COLOR=red];[/COLOR]

[COLOR=blue]int[/COLOR] main[COLOR=red]()[/COLOR]
[COLOR=red]{[/COLOR]
  TPatients Patients[COLOR=red];[/COLOR]
  Patients[COLOR=red].[/COLOR]Load[COLOR=red]();[/COLOR]

  [COLOR=blue]return[/COLOR] [COLOR=red][COLOR=black]0[/COLOR];[/COLOR]
[COLOR=red]}[/COLOR]
uPatients.h
Code:
// TPatients.h - Hier wird die Klasse und das Array Patients definiert, in dem dein Objekt der Klasse TPatient erzeugt wird
//#include <iostream>
//#include <string>
#include "uPatient.h"
using namespace std;

class TPatients
{

/*-------------      private     ---------------*/

  private:
    int Current;
    int size_of_Patients;

    /*int GetSizeOfPatients()
    {
      string text;
      int i;
      size_t pos_beg_tag, pos_end_tag, pos_beg_closetag;
      fstream file;  //Datei-Handle
      file.open("data.pv", ifstream::in); //Datei wird geöffnet
      while(!file.eof()) //Solange noch Daten vorhanden sind wird die Schleife ausgeführt
      {
          //text = ' ';
          getline(file, text); //Es wird jeweil immer eine Zeile ausgelesen
          //cout << text << endl;
          //pos_beg_tag = text.find_first_of('<') + 1;
          pos_end_tag = text.find_first_of('>');
          string attribute (text, pos_beg_tag, pos_end_tag-pos_beg_tag);
          if(attribute.compare("name") == 0)
          {
            ++i;
          }
          //cout << pos_beg_tag << endl;
          //cout << text << endl;
      }
      file.close();
      return i;
    }


/*-------------      public      ---------------*/

  public:

  /************      Konstruktor - Destruktor     ***************/

  TPatients()
  {
    size_of_Patients = GetSizeOfPatients();
    TPatient Patients[size_of_Patients];
    Current = -1;
    cout << "Patients wurde initalisiert..." << endl;
  }

  int GetSizeOfPatients()
    {
      string text;
      int i;
      size_t pos_beg_tag, pos_end_tag, pos_beg_closetag;
      fstream file;  //Datei-Handle
      file.open("data.pv", ifstream::in); //Datei wird geöffnet
      while(!file.eof()) //Solange noch Daten vorhanden sind wird die Schleife ausgeführt
      {
          //text = ' ';
          getline(file, text); //Es wird jeweil immer eine Zeile ausgelesen
          //cout << text << endl;
          //pos_beg_tag = text.find_first_of('<') + 1;
          pos_end_tag = text.find_first_of('>');
          string attribute (text, pos_beg_tag, pos_end_tag-pos_beg_tag);
          if(attribute.compare("name") == 0)
          {
            ++i;
          }
          //cout << pos_beg_tag << endl;
          //cout << text << endl;
      }
      file.close();
      return i;
    }

  /************      Load - Save     ***************/

  int Load()
  {
    string text;
    size_t pos_beg_tag, pos_end_tag, pos_beg_closetag;
    fstream file;  //Datei-Handle
    file.open("data.pv", ifstream::in); //Datei wird geöffnet
    while(!file.eof()) //Solange noch Daten vorhanden sind wird die Schleife ausgeführt
    {
        //text = ' ';
        getline(file, text); //Es wird jeweil immer eine Zeile ausgelesen
        cout << text << endl;
        pos_beg_tag = text.find_first_of('<') + 1;
        pos_end_tag = text.find_first_of('>');
        string attribute (text, pos_beg_tag, pos_end_tag-pos_beg_tag);
        if(attribute.compare("blood") == 0)
        {
          cout << endl;
        }
        //cout << pos_beg_tag << endl;
        //cout << text << endl;
    }
    return 0;
    //file.close();
  }

};
uPatient.h
Code:
//uPatient.h - Hier werden die Daten der einzelnen Personen in einem Objekt verwaltet
using namespace std;

class TPatient
{


  private:

    string Name;
    string FirstName;
    string Birthday;
    string Sex;
    string Street;
    string Number;
    string Zip;
    string Place;
    string HealthInsurance;
    string Blood;
  /*-------------      public      ---------------*/

  public:

  /************      Konstruktor - Destruktor     ***************/

  TPatient()
  {
    Name = "";
    FirstName = "";
    Birthday = "";
    Sex = "male";
    Street = "";
    Number = "";
    Zip = "";
    Place = "";
    HealthInsurance = "";
    Blood = "A-";
  }




  /************      Set-Methoden     ***************/

    int SetName(string Name)
    {
      this->Name = Name;
      return 0;
    }

    int SetFirstName(string FirstName)
    {
      this->FirstName = FirstName;
      return 0;
    }

    int SetBirthday(string Birthday)
    {
      this->Birthday = Birthday;
      return 0;
    }

    int SetSex(string Sex)
    {
      this->Sex = Sex;
      return 0;
    }

    int SetStreet(string Street)
    {
      this->Street = Street;
      return 0;
    }

    int SetNumber(string Number)
    {
      this->Number = Number;
      return 0;
    }

    int SetZip(string Zip)
    {
      this->Zip = Zip;
      return 0;
    }

    int SetPlace(string Place)
    {
      this->Place = Place;
      return 0;
    }

    int SetHealthInsurance(string HealthInsurance)
    {
      this->HealthInsurance = HealthInsurance;
      return 0;
    }

    int SetBlood(string Blood)
    {
      this->Blood = Blood;
      return 0;
    }


  /************      Get-Methoden     ***************


    string GetName()
    {

    }

    string GetFirstName()
    {

    }

    string GetBirthday()
    {

    }

    string GetSex()
    {

    }

    string GetStreet()
    {

    }

    string GetNumber()
    {

    }

    string GetZip()
    {

    }

    string GetPlace()
    {

    }

    string GetHealthInsurance()
    {

    }

    string GetBlood()
    {

    }*/

  /************      Load - Save - GetSizeOfPatients     ***************/

  int Load()
  {
    string text;
    size_t pos_beg_tag, pos_end_tag, pos_beg_closetag;
    fstream file;  //Datei-Handle
    file.open("data.pv", ifstream::in); //Datei wird geöffnet
    while(!file.eof()) //Solange noch Daten vorhanden sind wird die Schleife ausgeführt
    {
        //text = ' ';
        getline(file, text); //Es wird jeweil immer eine Zeile ausgelesen
        cout << text << endl;
        pos_beg_tag = text.find_first_of('<') + 1;
        pos_end_tag = text.find_first_of('>');
        string attribute (text, pos_beg_tag, pos_end_tag-pos_beg_tag);
        if(attribute.compare("blood") == 0)
        {
          cout << endl;
        }
        //cout << pos_beg_tag << endl;
        //cout << text << endl;
    }
    return 0;
    //file.close();
  }

};
 
Wie gesagt ich bin lange aus dem Geschäft, aber dass in einer Klassenkonstruktion Initialisierung möglich ist, wäre mir neu. Kann es sein, dass du irgendwas am Kompiler verstellt hast, damit er weniger Fehlermeldungen ausgibt?

Ich bezweifle, dass das ab dieser Zeile:
Code:
  /*int GetSizeOfPatients()
irgendwie kompiliert werden kann (wenn ich das richtig sehe, wird der Kommentar auch nicht beendet)
 
Was gibt der compiler aus wenn du WALL als Parameter anhängst?


Wie gesagt ich bin lange aus dem Geschäft, aber dass in einer Klassenkonstruktion Initialisierung möglich ist, wäre mir neu.

Doch in C++ geht das auf beide Weisen dann ists einmal lokal und einmal dynamisch gespeichert..
 
Das finde ich seltsam.

Eine Klassenkonstruktion ist ja erstmal nur eine Deklaration für den Kompiler, wann wird tu_was() ausgeführt, wenn ich sowas habe?
Code:
class Bla {
  tu_was();
  Bla() {} 
}
 
Ich denke nicht. Aber sowas sehe ich in dem Beispielcode auch spontan nicht. Oder auf welche Stelle bezogst du dich?
 
Auf das

Code:
// TPatients.h - Hier wird die Klasse und das Array Patients definiert, in dem dein Objekt der Klasse TPatient erzeugt wird
//#include <iostream>
//#include <string>
#include "uPatient.h"
using namespace std;

class TPatients
{

/*-------------      private     ---------------*/

  private:
    int Current;
    int size_of_Patients;

    /*int GetSizeOfPatients()
    {
      string text;
      int i;
      size_t pos_beg_tag, pos_end_tag, pos_beg_closetag;
      fstream file;  //Datei-Handle
      file.open("data.pv", ifstream::in); //Datei wird geöffnet
      while(!file.eof()) //Solange noch Daten vorhanden sind wird die Schleife ausgeführt
      {
          //text = ' ';
          getline(file, text); //Es wird jeweil immer eine Zeile ausgelesen
          //cout << text << endl;
          //pos_beg_tag = text.find_first_of('<') + 1;
          pos_end_tag = text.find_first_of('>');
          string attribute (text, pos_beg_tag, pos_end_tag-pos_beg_tag);
          if(attribute.compare("name") == 0)
          {
            ++i;
          }
          //cout << pos_beg_tag << endl;
          //cout << text << endl;
      }
      file.close();
      return i;
    }
Wobei ich aber eher vermute, dass hier mal wieder ein paste&copy Fehler aufgetreten ist, da der angefangene Kommentar wohl völliger Murks ist und da nicht hingehört
 
Zurück
Oben