Zeilenweise lesen einer Datei

Du bist neu in der Welt von C++? Dann schau hier herein!
Antworten
Freakadel
Beiträge: 4
Registriert: 21. Oktober 2019 10:33

Zeilenweise lesen einer Datei

Beitrag von Freakadel » 14. Juli 2020 12:10

Hallo liebe Community,

ich habe eine Textdatei, die ich mit getline zeilenweise einlese, bevor ich jetzt zu meinem Problem komme, zeige ich euch kurz den Aufbau meiner Textdatei:

Aufgebaut ist die Textdatei folgend:

Anlage1 Temp1 °C 0.00 100.00 K01
Anlage1 Druck1 bar 0.00 4.00 K02
Anlage1 Druck2 <leer> 0.00 6.00 K03

Zwischen den einzelnen Tags oder Variablen ist kein Leerzeichen vorhanden, sondern ein Tabulator. Alles noch soweit kein Problem, aber es kann durchaus vorkommen, wie hier im Beispiel der Druck2 keine Einheit führt. Wie hier funktioniert das zeilenweise lesen mit einem einfachen Tabulator nicht mehr.

Wie kann ich jetzt den string so bearbeiten, dass ich dieses leere Feld trotzdem erkenne und überspringe? Ich muss den unteren und oberen Grenzwert trotzdem korrekt einlesen können. Aktuell würde er mit einem Tab die komplette Zeile verschieben, das darf nicht passieren.

Also folgende Funktionen müssen gegeben sein:
1. Korrektes Einlesen aller Variablen an der korrekten Stelle
2. Leere Felder erkennen und leer ausgeben oder überspringen
3. auch zwei oder drei leere Felder hintereinander könnten in der Datei vorkommen, also es würde die Einheit und der komplette Messbereich fehlen.

Für Ratschläge und Hilfen bin ich sehr dankbar.

Zum krönenden Abschluss, mein Code, den ich soweit einlese.

Code: Alles auswählen

   
    string zeile;
    string file_anlage;
    string file_opcname;
    string file_channel;
    string file_unit;
    string s_file_lowerrange;
    string s_file_upperrange;
    double file_lowerrange;
    double file_upperrange;

    while (getline(read_file, zeile))
    {
        // Teile eingelesenen String in einzelne Variablen auf.
        stringstream zeilenpuffer(zeile);
        zeilenpuffer >> file_anlage >> file_opcname >> file_unit >> file_lowerrange >> file_upperrange >> file_channel;
        
        addChannelNode(file_anlage, file_opcname, file_unit, file_lowerrange, file_upperrange, file_channel);
        ...
Alternativ wollte ich folgenden Code probieren, das geht aber schief und funktioniert nicht:

Code: Alles auswählen

    ifstream read_file ((char*) currentpath.c_str());
    string zeile;
    string file_anlage;
    string file_opcname;
    string file_channel;
    string file_unit;
    string s_file_lowerrange;
    string s_file_upperrange;
    double file_lowerrange;
    double file_upperrange;

    while (getline(read_file, zeile))
    {
        int PosA {0};
        int PosE = zeile.find('\t', PosA);

        // Lese Anlagenname aus
        file_anlage = zeile.substr(PosA, PosE-PosA);
        PosA = PosE;
        PosE = zeile.find('\t', PosA);

        // Lese Opc-Namen aus
        file_opcname = zeile.substr(PosA, PosE-PosA);
        PosA = PosE;
        PosE = zeile.find('\t', PosA);

        // Lese Einheit aus
        file_unit = zeile.substr(PosA, PosE-PosA);
        PosA = PosE;
        PosE = zeile.find('\t', PosA);

        // Lese untere Anlagengrenze aus
        s_file_lowerrange = zeile.substr(PosA, PosE-PosA);
        PosA = PosE;
        PosE = zeile.find('\t', PosA);

        // Lese obere Anlagengrenze aus
        s_file_upperrange = zeile.substr(PosA, PosE-PosA);
        PosA = PosE;
        PosE = zeile.find('\t', PosA);

        file_lowerrange = std::stof(s_file_lowerrange);
        file_upperrange = std::stof(s_file_upperrange);

        // Lese absolute Kanaladdresse aus
        file_channel = zeile.substr(PosA, PosE-PosA);
        PosA = PosE;
        PosE = zeile.find('\t', PosA);
        .
        .
        .

Antworten