Forum: PC-Programmierung CPP ASCII-Datei Auslesesen


von Matze (Gast)


Lesenswert?

Hallo,

Ich möchte zum Ende meines Programms eine ASCII-Datei erzeugen, und 
diese beim Programmstart wieder auslesen.
1
fstream ziel("Datei.txt");
2
    int pos=0;
3
    ziel.seekp(0);       //Schreibzeiger
4
    ziel<<"Meine 1. Datei";
5
    ziel.seekg(0);      //Lesezeiger
6
    string word;
7
    while(ziel>>word)
8
    {
9
        if((word[0] >= 'a' && word[0] <= 'z') || (word[0] >= '0' && word[0] <= '9') || (word[0] >= 'A' && word[0] <= 'Z')) //
10
        cout<<word;
11
        cout<<" ";
12
    }
13
    cout<<endl;
14
    ziel.close();

Seltsamerweise bekomme ich als Ausgabe:
"Meine 1. Dateiatei".

Woher kommt das atei?

grüße
Matze

von Matze (Gast)


Lesenswert?

Was ich gestern schrieb sagt nicht sehr viel aus, dashalb nochmal 
ausführlicher.

Ich versuche zum 1. mal eine ascii-Datei zu erstellen und sie danach 
wieder auszulesen.

Die Datei soll Datei.txt heissen,
sie wird durch fstream erstellt uns soll durch ziel angesprochen werden.

Ich setze sowohl den Lese als auch den Schreibzeiger auf die Position 0.
dann schreibe ich in die Datei "Meine 1. Datei"

durch die >> Stromzeichen gelingt es sie Wort für Wort, jeweils getrennt 
durch " " wieder auszulesen.

Durch die if-Abfrage werden die " " welche nicht mit ausgelesen werden 
wieder eingefügt.

Somit wird der Inhalt der Datei auf der Konsole wausgegeben.

Seltsam ist nun, dass in der Datei zwar "Meine 1. Datei" steht.
Auf der Konsole jedoch "Meine 1. Dateiatei" geschrieben wird.

Compiler ist wx-Dev-Cpp 6.10.2

Kompletter Code:
1
#include <cstdlib>
2
#include <iostream>
3
#include <fstream>
4
#include "main.h"
5
6
using namespace std;
7
8
int main(int argc, char *argv[])
9
{    
10
    fstream ziel("Datei.txt");
11
    ziel.seekp(0);       //Schreibzeiger
12
    ziel<<"Meine 1. Datei";
13
    ziel.seekg(0);      //Lesezeiger
14
    string word;
15
    while(ziel>>word)
16
    {
17
        if((word[0] >= 'a' && word[0] <= 'z') || (word[0] >= '0' && word[0] <= '9') || (word[0] >= 'A' && word[0] <= 'Z')) //
18
        cout<<word;
19
        cout<<" ";
20
    }
21
    cout<<endl;
22
    ziel.close();
23
    system("PAUSE");
24
    return EXIT_SUCCESS;
25
}

von Rainer V. (rudi994)


Lesenswert?

Hallo Matze!

Mangels Ahnung von Cpp suche ich noch in Tutorials. Mir fehlt für den 
fstream eine Funktion zum Zurücksetzen von Zugriffsfehlern. Deinen o.g. 
Code habe ich unter CodeBlocks als Cpp-Konsolen-Anwendung kompiliert. Im 
Programm wird die Datei geschrieben, kann aber nicht gelesen werden, da 
sie ja durch den 1. Zugriff im Schreibmodus ist.

Die Datei muß geschlossen und im Lesemodus wieder geöffnet werden. Da in 
fstream ziel("Datei.txt") keine ios-Parameter als Dateimodus angegeben 
sind, muß die Datei schon existieren. Sonst gibt es einen Fehler. Hier 
sind Anweisungen für fstream ziel, das Programm läuft bei mir fehlerfrei 
mit Ausnahme der while-Schleife zum Datei-Lesen:

#define s_fname "C:/Datei1.txt" // voller Pfad zum Wiederfinden

fstream ziel; // Deklaration des Datei-Stream "ziel"

ziel.open(s_fname, ios::out); // Erzeugt und öffnet eine neue Datei im 
Schreibmodus. Eine schon vorhandene Datei wird dabei gelöscht!

ziel.open(s_fname, ios:out|ios::app); // Öffnet eine vorhandene Datei im 
Schreibmodus zwecks Anfügen von Text. Dateizeiger wird an das Datei-Ende
gesetzt. Existiert die Datei nicht, so wird sie neu erzeugt.

ziel.open(s_fname, ios::in); // Öffnet eine schon vorhandene Datei im 
Lesemodus. Wenn die Datei nicht existiert, tritt ein Zugriffsfehler auf.

ziel.close(); // Datei schließen. Der Stream bleibt aber bestehen.

fstream ziel(s_fname, ios-Parameter); // Deklariert Datei-Stream ziel 
und öffnet die Datei im durch den/die Parameter angegebenen Modus. 
Mehrfache Parameter können kombiniert werden und sind dabei durch das 
OR-Zeichen (|) zu trennen. Außer den Parametern in o.g. Anweisungen gibt 
es weitere.

Sobald bei einer dieser Anweisungen ein Zugriffsfehler auftritt, werden 
weitere Zugriffe auf den Stream "ziel" gesperrt. Um Fehler zu prüfen, 
habe ich hinter den Zugriffen eine Fehlerabfrage eingefügt. Etwa so:

if (!ziel) { cout<<"Fehler in Zeile xyz"<<endl; goto Fortsetzung; }

Direkt hinter while (ziel>>word) {...} bzw. nachdem der Text bis zum 
Ende aus der Datei gelesen wurde, tritt ein Zugriff-Fehler auf. Ich 
vermute vorsichtig, daß der Fehler durch Lesen über das Datei-Ende (EOF) 
hinaus auftritt, wodurch das Lesen beendet wird.

File-Seek-Befehle habe ich weggelassen. Ich konnte mir den Zweck nicht 
erklären. Das Programm hat ja trotzdem soweit funktioniert.

Wenn ein Stream wegen Fehler gesperrt ist, kann man mit einem weiteren 
Stream die Datei wieder verarbeiten. Aber das löst das Problem nicht.

Der Sache mit "atei" bin ich nicht auf die Schliche gekommen. Bei mir 
wird der Text korrekt angezeigt. Vllt. fällt mir dazu noch was ein.

Übrigends: wenn man nach fstream ziel("Datei.txt"), also ohne die ios-
Parameter, einen Text in die Datei schreibt, dann wird schon vorhandener 
Text nicht gelöscht, sondern beginnend am Dateianfang überschrieben.

LG

: Bearbeitet durch User
von Mark B. (markbrandis)


Lesenswert?

Wenn Du zwei verschiedene Dinge tun willst, nämlich einmal von einer 
Datei lesen und ein anderes Mal von einer Datei schreiben (auch wenn es 
am Ende die gleiche Datei ist), dann mach es auch so. Also mit zwei 
verschiedenen Funktionen.

Ach ja, und man sollte sich nie blind darauf verlassen dass eine Datei 
(oder andere Ressource) erfolgreich geöffnet wurde. Fehler passieren 
immer mal.


Beispiel:

1
#include <fstream>
2
#include <iostream>
3
#include <string>
4
5
using namespace std;
6
7
void read_file_and_print(const string& quelldatei)
8
{   
9
    ifstream myInputFile;
10
    myInputFile.open(quelldatei.c_str());
11
    
12
    if (myInputFile.is_open()) {
13
        string s;
14
        while(!myInputFile.eof()) {
15
            getline(myInputFile, s);
16
            cout << s << endl;
17
        }
18
        myInputFile.close();
19
    }
20
    else {
21
        cout << "Error: file " << quelldatei << " could not be opened." << endl;
22
    }    
23
}
24
25
void write_file(const string& zieldatei, const string& to_write)
26
{
27
    ofstream myOutputFile;
28
    myOutputFile.open(zieldatei.c_str(), ios::app);
29
    
30
    if (myOutputFile.is_open()) {
31
        myOutputFile << to_write;
32
        myOutputFile.close();
33
    }
34
    else {
35
        cout << "Error: file " << zieldatei << " could not be opened." << endl;
36
    }
37
}
38
39
int main()
40
{   
41
    string quelldatei = "Datei.txt";
42
    string zieldatei  = "Datei.txt";
43
    string to_write   = "something";
44
    
45
    cout << "Opening file " << quelldatei << " and printing its content:" << endl;
46
    read_file_and_print(quelldatei);
47
    
48
    cout << endl << "Appending " << to_write << " to the file " << zieldatei << endl;
49
    write_file(zieldatei, to_write);
50
    
51
    cout << endl << "Reading again: " << endl;
52
    read_file_and_print(quelldatei);
53
54
    return 0;
55
}

: Bearbeitet durch User
von Klaus W. (mfgkw)


Lesenswert?

Das eigentliche Problem (wieso kommt ein nicht erwarteter Rest aus der 
Datei?) könnte davon kommen, daß die Datei nicht jedesmal neu angelegt 
wird.
Eventuell steht von früheren Versuchen noch etwas drin.
Nur der Anfang wird überschrieben, der Rest bleibt erhalten und wird mit 
gelesen.
Das kann man verhindern, indem man so öffnet:
  std::fstream ziel( "Datei.txt", std::fstream::in | std::fstream::out | 
std::fstream::trunc );

Dadurch wird der alte Inhalt anfangs weggeworfen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.