# Datei auslesen



## fettyteddy (14. Februar 2007)

Hallo,

ich bin gerade beim lernen von C++. Ich möchte eine Datei Zeilenweise auslesen und dann einen Teilstring in einer Variable Speichern. 

**** Bsp. config.ini *********

Zeile 1:   dateiname=daten.txt

*****************************

Eigentlich benötige ich dann denn Teil "daten.txt" als string um damit weiter zu Arbeiten...

**** cpp ********************

#include <iostream>
#include <fstream>
using namespace std;

int main () {
  char z, str[256];
  ifstream is;

  sprintf( str, "config.ini" );

  is.open (str);        // open file

  while (is.good())     // loop while extraction from file is possible
  {
    z = is.get();

  }
  cout << z;   // z ist leer 
  is.close();           // close file


  getchar ();
  getchar ();
  return 0;
}

**********************************

wie muss ich die Zeile übergeben, das der String auch in z gespeichert wird? komme da echt nicht weiter und hoffe mir kann jemand helfen.


----------



## Cooper3210 (14. Februar 2007)

Hallo
meinst du das so ?

```
#include <iostream> // wegen cout cin
#include <fstream> // wegen Dateistreamobjekt
#include <string> // wegen Datentyp string

using namespace std;


int main(int argc, char *argv)
{
            ifstream file;
            
            string fileName = "c:\\test.txt";
            file.open(fileName.c_str(), ios::in | ios::binary); // oeffen im Binaer-Modus
            if(file)
            {
                        file.seekg(0, ios::end); // zum Ende Datei springen
                        long fileSize = file.tellg(); // Dateigroesse auslesen
                        file.seekg(0); // Zurueck zum Anfang springen
                        char *text = new char[fileSize]; // Speicher fuer Text anlegen
                        file.read(text, fileSize); // Text in 1 Rutsch auslesen
                        file.close();
                        cout << text; 
                        delete text; // Speicher aufraeumen 
            }
            else
            {
                        cout << "Fehler!";
            }
            cin.get();
            return 0;
}
```

MFG cooper


----------



## MCoder (14. Februar 2007)

Die Abfrage "is.good()" ist am Anfang der Schleife nicht günstig, weil dann der Fehler schon passiert ist: nämlich beim Lesen des letzten Zeichens, so dass "z" immer leer ist. Abgesehen davon ist deine Variante nicht für zeilenweises Lesen geeignet, da "z" nur ein einziges Zeichen aufnehmen kann.
Hier mal ein Vorschlag für zeilenweises Lesen einer Textdatei:

```
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main()
{
    string str;
    ifstream is("config.ini");

    if( is.is_open() )
    {
        while( getline(is, str) )
        {
            cout << str << endl;
        }                        
    
        is.close()
    }    

    return 0;    
}
```
Gruß
MCoder


----------



## Cooper3210 (14. Februar 2007)

Hi 
wenn du das Zeilen für zeile haben möchtest :


```
#include <iostream> // wegen cout cin
#include <fstream> // wegen Dateistreamobjekt
#include <string> // wegen Datentyp string

using namespace std;

int main(int argc, char *argv)
{
            ifstream file;
            string fileName = "c:\\config.ini";
            
            file.open(fileName.c_str()); //  oeffen im Text-Modus
            if(file)
            {
                        string text; // Haupttext
                        while(!file.eof())
                        {
                                    char buffer; // Buffer
                                    file.get(buffer);
                                    text += buffer; // Zeichen zusammensetzen 
                        }
                        cout << text; // fertigen Text ausgeben
                        file.close();
            }
            else
            {
                        cout << "Datei Fehler!";
            }
            cin.get();
            return 0;
}
```
MFG COOPER


----------



## deepthroat (14. Februar 2007)

Hi.





Cooper3210 hat gesagt.:


> ```
> while(!file.eof())
> {
> char buffer; // Buffer
> ...


Viel zu umständlich - und wegen der Verwendung von !file.eof() auch *falsch*. Mach es lieber so wie MCoder geschrieben hat!

Gruß


----------



## Cooper3210 (15. Februar 2007)

Hi 
mal abgesehen davon das es ein langer weg ist .....
Aber bitte was ist das falsch?
Geht doch !
MFg coper


----------



## fettyteddy (15. Februar 2007)

also vielen Dank für die Hilfe hat super geklappt! 

Ich hätte da aber nochmal ne andere Frage und hoffe Ihr könnt mir da mal nen kleinen Tip zur Realisierung geben. Ich schreibe an einem Tool (unter Linux), das ...

1. config file einliest (FERTIG)
2. ein Verzeichnis überwachen soll ()
3. sobald eine Datei hinzukommt prüft ob am Ende in der Datei "EOF" steht.
- hat den Hintergrund, dass die Datein mit sftp auf den Server geschoben wird und bei großen Dateien muss sicher gestellt sein, dass die Datei auch vollständig im Verzeichnis angekommen ist und nicht noch kopiert wird. (FERTIG)
4. Eingespielte Datei in anderen Ordner verschieben (bin ich dran)
5. Ein PHP Script aufruft, dass die Datei weiter verarbeitet (suche ich noch den Befehl)

Das Problem sehe ich bei 4. ich denke, dass Auslesen bekomme ich mit getDir irgendwie hin, nur muss das Tool ja in einer ständigen Schleife laufen und ich hab nen paar bedenken, dass ganze in ne  "while" Schleife zu Packen. Aber es muss ohne Pause laufen. Bei Visual C++ unter Windows gibts das ja als vordefiniertes Steuerelement, aber das Tool soll unter Linux laufen. Gibts da vielleicht unter C++ noch ne sauberere Lösung als ne "while", auch in Bezug auf die Ressourcen.

Danke nochmal


----------



## deepthroat (15. Februar 2007)

Hi.





Cooper3210 hat gesagt.:


> Hi
> mal abgesehen davon das es ein langer weg ist .....
> Aber bitte was ist das falsch?
> Geht doch !


Das ist ein Irrtum - das Programm ist nicht korrekt. Mal abgesehen davon, das *zeilenweise* ausgelesen werden sollte - nicht zeichenweise.

Nahezu mit 100%iger Wahrscheinlichkeit ist ein Programm in der eine !s.eof()-Schleife verwendet wird falsch und wird nicht immer richtig funktionieren (Das das Programm unter bestimmten Umständen funktioniert will ich ja gar nicht bestreiten). Ein Buch in dem das so empfohlen wird sogleich dahinstellen wo es hingehört: in den Papierkorb.

Beispiel:
	
	
	



```
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main() {
  ifstream in("test1.txt");
  ofstream out("test2.txt");

  string text;

  while(!in.eof()) {
    char c;
    in.get(c);
    text += c;
  }
  out << text;
  
  in.close();
  out.close();
}
```
Ich denke du stimmst mit mir insoweit überein, das nach der Ausführung des Programms die Datei test2.txt genau den gleichen Inhalt haben sollte wie die Datei test1.txt. (Vorausgesetzt deine Methode mit dem !eof() funktioniert)

Bei mir ist das allerdings nicht der Fall! Die Dateien sind unterschiedlich groß und eben nicht gleich.

Das liegt daran, das der C ++ Standard nicht vorschreibt wann der Test auf "EOF" wahr wird (ob bevor oder nachdem versucht wird hinter das letzte Zeichen im Stream zu lesen) und du dementsprechend einfach auch das gelesene EOF Zeichen vom Stream mit an den String anhängst weil du nicht die Eingabeoperation nochmal geprüft hast.

Außerdem ist das Ende des Streams nur ein möglicher "Fehlerzustand". Das bedeutet das Programm hängt evtl. endlos in der Schleife und wird dann nur irgendwann beendet weil kein Speicher mehr für den String alloziert werden kann falls der Stream in einen anderen Fehlerzustand übergeht (z.B. bei einem Lesefehler o.ä.). [ist ein Stream in einem Fehlerzustand kann von ihm nichts mehr gelesen werden - das überprüfst du aber überhaupt nicht]

Gruß

/edit: @fettyteddy: Die Verwendung von while (is.good())  ist übrigens genauso schlecht.


----------



## Cooper3210 (16. Februar 2007)

Hi
vielen dank !
Da habe ich wieder was gelernt und muss zugeben das die erklärung 100 Punkte bekommt.
Danke Schön ........
MFg cooper


----------

