tutorials.de Buch-Aktion 05/2012
ERLEDIGT
NEIN
ANTWORTEN
7
ZUGRIFFE
2425
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    LadyMarion LadyMarion ist offline Mitglied Bronze
    Registriert seit
    Mar 2005
    Beiträge
    41
    Hallo,

    ich möchte gerne folgendes machen:

    Ich habe mehrere Dateien, die eingelesen werden sollen. Die Dateien enthalten Variablen, mit denen anschließend weiter gerechnet werden soll.

    Dafür habe ich in der Klasse "test" eine allgemeine read-Funktion zur Verfügung, die alle Dateien einfach nur einliest, sowie eine find-Funktion, die mir anhand eines Schlüsselwortes den jeweiligen Wert zurückgibt.
    Früher waren die read- und die find-Funktion in einer zusammengefasst, jetzt wollte ich die Funktionen aber aufteilen, so dass es nur noch eine einzige read-Funktion im ganzen Programm gibt und nur die find-Funktion je nach Datei anders aussieht.

    In der main-Funktion rufe ich also folgende Funktionen auf:
    Code :
    1
    2
    3
    4
    5
    6
    7
    
    int main()
    {
        test frage;
        frage.read("datei.txt");
        frage.find("ABC");
        return 0;
    }

    Die read-Funktion könnte dann ja so aussehen:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    bool test::read(const string dateiname)
    {
        ifstream IN;
        IN.open (dateiname.c_str());
        if (IN.good())
        {
            string zeile;
            while (getline(IN, zeile))
            {
                if (!zeile.empty())
                {
                    return true;
                }
            }
        }
        else
        {
            cout<<"FEHLER\n";
            return false;
        }
        IN.close();
    }

    In der find-Funktion werden später dann mehrere Fälle für die unterschiedlichen Dateien unterschieden, aber bis jetzt sieht es so aus:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    const double test::find(const string& schluesselwort) const
    {
        string zeile;
        double wert;
        if (zeile.find(schluesselwort) != string::npos)
        {
            // hier wird dann die entsprechende Zeile zerlegt und der Wert herausgeschrieben
            return wert;
        }
    }
    Wie muss ich denn jetzt die beiden Funktionen "verknüpfen", dass es dann auch funktioniert? Denn bis jetzt weiß ja die find-Funktion nicht, wo sie eigentlich nach dem Schlüsselwort suchen soll...

    Vielen Dank schon mal!
     

  2. #2
    MCoder MCoder ist offline Mitglied Diamant
    tutorials.de Premium-User
    Registriert seit
    Jul 2005
    Ort
    München
    Beiträge
    2.448
    Hallo,

    du must die eingelesenen Zeilen irgendwo speichern und diese Daten dann an die "find()"-Funktion übergeben. Dafür könntest du z.B. die Klasse "vector" verwenden.

    Gruß
    MCoder
     
    "The three chief virtues of a programmer are: Laziness, Impatience and Hubris."
    --- Larry Wall

  3. #3
    LadyMarion LadyMarion ist offline Mitglied Bronze
    Registriert seit
    Mar 2005
    Beiträge
    41
    Erstmal danke.

    Geht das nur mit vector, oder kann ich die Zeilen nicht auch einfach in einem string speichern?

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
    bool test::read(const string dateiname)
    {
        ifstream IN;
        IN.open (dateiname.c_str());
        if (IN.good())
        {
            string zeile;
            while (getline(IN, zeile))
            {
                if (!zeile.empty())
                {
    [B]                test::bsp = line;[/B]
                }
            }
            return true;
        }
        else
        {
            cout<<"FEHLER\n";
            return false;
        }
        IN.close();
    }


    Dementsprechend heißt es dann in der find-funktion:
    ...
    if (test::bsp.find(schluesselwort) != string::npos)
    ...

    Nur wenn ich das so mache, dann steht in dem string "bsp" natürlich nur die letzte Zeile. Geht das nicht auch, dass ich alle Zeilen zur Verfügung hab?
     

  4. #4
    MCoder MCoder ist offline Mitglied Diamant
    tutorials.de Premium-User
    Registriert seit
    Jul 2005
    Ort
    München
    Beiträge
    2.448
    Zitat Zitat von LadyMarion Beitrag anzeigen
    Geht das nur mit vector, oder kann ich die Zeilen nicht auch einfach in einem string speichern?
    Du kannst die Zeilen natürlich in jeder Form speichern, die du als sinnvoll erachtest (und die technisch machbar ist).
    Falls die Zeilen nur aus einem Wort bestehen (etwa dem Variablennamen) kann man auch vernünftig damit arbeiten, wenn alles in einen einzigen String abgelegt wird. Sind die Zeilen selbst noch irgendwie strukturiert, ist es aber besser, diese auch separat zu speichern, weil damit die spätere Verabeitung einfacher wird.

    Bei deinem Code musst du die einzelnen Zeilen zum Zielstring aufaddieren:
    Code cpp:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    
    bool test::read(const string dateiname)
    {
        ifstream IN;
        IN.open (dateiname.c_str());
        if (IN.good())
        {
            test::bsp = "";
        
            string zeile;
            while (getline(IN, zeile))
            {
                if (!zeile.empty())
                {
                    test::bsp += (" " + line); // Aufaddieren mit einem Leerzeichen als Trennzeichen
                }
            }
            return true;
        }
        else
        {
            cout<<"FEHLER\n";
            return false;
        }
        IN.close();
    }
    Gruß
    MCoder
    Geändert von MCoder (21.01.08 um 15:55 Uhr)
     
    "The three chief virtues of a programmer are: Laziness, Impatience and Hubris."
    --- Larry Wall

  5. #5
    LadyMarion LadyMarion ist offline Mitglied Bronze
    Registriert seit
    Mar 2005
    Beiträge
    41
    Ok, danke. Das ist mir jetzt soweit klar. Aber irgendwie funktioniert das so auch nicht...

    Die Dateien, die gelesen werden sollen, sind verschieden, sowohl in der Zeilen-, als auch in der Spaltenanzahl. Deshalb wollte ich in der read-Funktion die Datei einfach nur komplett einlesen und dann je nachdem in der find-Funktion nach dem entsprechenden Wert suchen.

    Eine Datei sieht z.B. so aus:
    ABC|1.2|Kommentar
    Über das Schlüsselwort ABC will ich also an den Wert 1.2 kommen, was in der find-Funktion auch funktioniert.

    Eine andere Datei sieht nun aber so aus:
    AB CD EF GH
    1.2 3.2 3.4 a
    3.4 4.5 4.8 b
    Hier werden, abhängig von einem bestimmten "GH" (hier also a oder b), die anderen Werte in der Zeile eingelesen, was in der find-Funktion auch bereits funktioniert.

    Nur funktioniert es eben nicht, dass ich alle Zeilen einlese, ich habe immer nur die letzte Zeile. Ich weiß jetzt grad echt nicht, wie ich das mit einem Vector realisieren kann.
    Könnt Ihr mir da vielleicht etwas auf die Sprünge helfen?
     

  6. #6
    MCoder MCoder ist offline Mitglied Diamant
    tutorials.de Premium-User
    Registriert seit
    Jul 2005
    Ort
    München
    Beiträge
    2.448
    Hallo,

    eigentlich sollte bei der Addition alles in einer Zeile stehen

    Hier ist jedenfalls mal bein Beispiel für die Anwendung eines Vectors. Ich habe auch mal deine Lesefunktion etwas modifiziert, da etwa das "IN.close();" nie aufgerufen wurde.
    Code cpp:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    
    // Einlesen
    bool test::read(const string dateiname, vector<string>& lines)
    {
        ifstream IN(dateiname.str());
        
        if( IN.is_open() )
        {
            string zeile;
            
            while( getline(IN, zeile) )
            {
                if( !zeile.empty() )
                {
                    lines.push_back(zeile);
                }
            }
            
            IN.close();
            return true;
        }
        else
        {
            return false;
        }        
    }
     
    // Suchen
    bool test::find(string str, vector<string> lines)
    {
        vector<string>::iterator it;
        
        for( it = lines.begin(); it != lines.end(); ++it )
        {
            string strLine = *it;
            
            if( ... ) // TODO: Zeile auswerten
            {
                return true;
            }    
        }
     
        return false;
    }
     
    // Anwendung
    vector<string> lines;    
     
    if( read("C:\\datei.xyz", lines)
    {
        if( find("ABC", lines) )
        {
            // ...
        }
    }
    Gruß
    MCoder
     
    "The three chief virtues of a programmer are: Laziness, Impatience and Hubris."
    --- Larry Wall

  7. #7
    LadyMarion LadyMarion ist offline Mitglied Bronze
    Registriert seit
    Mar 2005
    Beiträge
    41
    Hallo,

    erstmal vielen, vielen Dank für Deine Hilfe!

    Ich hab das jetzt soweit eingebaut und es funktioniert auch alles. Jetzt hätte ich aber nochmal was

    Ich habe folgende Datei:
    AB CD EF GH
    1.2 3.2 3.4 a
    3.4 4.5 4.8 b
    9.8 7.4 2.4 c

    Wenn ich hier jetzt nur eine bestimmte Zeile lesen will, dann muss ich doch die entsprechende Zeile als Parameter in der find-Funktion übergeben, oder?

    Ich hab jetzt schon versucht, das an mehreren Stellen irgendwie unterzukriegen, aber irgendwie haut es nicht hin...

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    
    // Einlesen
    bool test::read(const string dateiname, vector<string>& lines)
    {
        ifstream IN(dateiname.str());
        
        if( IN.is_open() )
        {
            string zeile;
            
            while( getline(IN, zeile) )
            {
                if( !zeile.empty() )
                {
                    lines.push_back(zeile);
                }
            }
            
            IN.close();
            return true;
        }
        else
        {
            return false;
        }        
    }
     
    // Suchen
    bool test::find(string str, vector<string> lines, [B]int i[/B])
    {
        vector<string>::iterator it;
        
        for( it = lines.begin(); it != lines.end(); ++it )
        {
            string strLine = *it;
     
    [B]        if (strLine == lines[i]) {[/B]
            
            if( ... ) // TODO: Zeile auswerten
            {
                return true;
            }    
            [B]}[/B]
     
        }
     
        return false;
    }
     
    // Anwendung
    vector<string> lines;    
     
    if( read("C:\\datei.xyz", lines)
    {
        if( find("ABC", lines, [B]2[/B]) )
        {
            // ...
        }
    }

    So erhalte ich jetzt zwar keine Fehlermeldung mehr beim Compilieren, aber die Werte werden auch nicht ausgegeben...

    Wäre wirklich sehr dankbar, wenn ich nochmal ein bißchen Hilfe bekommen könnte...
     

  8. #8
    MCoder MCoder ist offline Mitglied Diamant
    tutorials.de Premium-User
    Registriert seit
    Jul 2005
    Ort
    München
    Beiträge
    2.448
    Hallo,

    wenn du schon weisst, welche Zeile du ansprechen willst, kannst du auf die Iteration durch den Vector (die for-Schleife) verzichten und die Zeile gleich über ihren Index ansprechen. Dafür würde ich eine separate find-Methode spendieren, die dann drei Parameter hat (Stichwort: Überladen von Methoden).

    Bei der Anwendung der Vergleichsoperatoren zum String muss du darauf achten, was du erreichen willst:
    Code cpp:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    if( strLine == lines[i] ) // strLine ist absolut IDENTISCH zu lines[i]
    {
     
    }
     
    if( lines[i].find_first_of(strLine) ) // strLine ist in lines[i] enthalten
    {
     
    }
     
    // usw.
    Gruß
    MCoder
     
    "The three chief virtues of a programmer are: Laziness, Impatience and Hubris."
    --- Larry Wall

Ähnliche Themen

  1. XML-Datei einlesen und Objekt zurückgeben
    Von ara-art im Forum Flash Plattform
    Antworten: 1
    Letzter Beitrag: 15.04.09, 12:57
  2. Problem: Werte aus Datei in Map einlesen?
    Von LadyMarion im Forum C/C++
    Antworten: 0
    Letzter Beitrag: 12.08.08, 10:36
  3. Problem beim TXT-Datei einlesen
    Von freek0815 im Forum Java
    Antworten: 2
    Letzter Beitrag: 10.09.07, 08:51
  4. Problem beim Datei einlesen
    Von avenger2099 im Forum C/C++
    Antworten: 7
    Letzter Beitrag: 18.05.05, 10:37
  5. Problem beim einlesen einer Datei
    Von micha72 im Forum PHP
    Antworten: 13
    Letzter Beitrag: 09.02.05, 20:19