2016-10-11 3 views
0

Ich arbeite derzeit mit std::fstream und haben die folgende Klasse: (Beachten Sie, dass die Datei auf Konstruktor geöffnet ist und nur während alle Lese-/Schreibvorgänge geöffnet bleiben soll schließen, wenn sie zerstört sind).Schreiben Sie in einen bereits geöffneten Filestream und entfernen Sie den Rest

MyFileClass 
{ 
public: 
    MyFileClass(const std::string& file_name) { m_file.open(file_name) }; 
    ~MyFileClass() { m_file.close() }; 
    bool read(std::string& content); 
    bool write(std::string& data); 
private: 
    std::fstream m_file; 
} 

Jetzt habe ich einige Beispiel-Code:

MyFileClass sample_file; 
sample_file.write("123456"); 
sample_file.write("abc"); 

Ergebnis wird „abc456“, weil, wenn der Strom geöffnet ist und wir mit truncate-Modus zu schreiben es immer an der Spitze schreiben wird, was zur Zeit ist da drin.

Was ich gerne haben würde, ist aufzuräumen jedes Mal, bevor wir so am Ende schreiben, ich werde nur das Neueste haben, in diesem Fall "abc".

Und das aktuelle Design ist, wenn die Datei nicht da ist, wird nur beim Schreiben erstellt, aber nicht beim Lesen (lesen wird Fehlercode zurückgegeben, wenn die Datei nicht vorhanden ist).

Meine Schreibfunktion ist:

bool 
MyFileClass::write(const std::string& data) 
{ 
    m_file.seekg(0); 
    if (!m_file.fail()) 
    { 
     m_file << data << std::flush; 
    } 

    return m_file.fail() ? true : false; 
} 

Gibt es eine Möglichkeit den aktuellen Inhalt der Datei zu löschen, bevor die Daten Spülung?

+1

C++ bietet keine Möglichkeit, eine bereits geöffnete Datei zu kürzen. Siehe http://stackoverflow.com/questions/20809113/how-to-truncate-a-file-while-it-is-open-with-fstream – Barmar

+0

Anders als das erneute Öffnen der Datei, nein. – UKMonkey

Antwort

0

in der Lage sein, an das Ende der Datei zu schreiben, verwenden Sie stattdessen Flag ios :: app.

Code ist voller Fehler:

1- Sie auch eine Klasse String zu schreiben versucht, die Datei ist nicht korrekt. Wenn Sie dies tun möchten, verwenden Sie die Serialisierung. In Ihrem Fall konvertieren Sie es einfach in eine konstante Zeichenkette.

2- Ihre Schreib- und Lesefunktionen sind so definiert, dass sie einen Verweis auf eine Zeichenfolge enthalten, aber Sie übergeben einen Wert! (Übergeben von "12345" und "abc")

3- Warum suchen Sie den Eingabezeiger? (seekg)? solange du versuchst zu schreiben ?? !! Sie können seekp() suchen Ausgangszeiger; auch in diesem Fall, aus welchem ​​Grund, dies zu tun? Wenn Sie Text an das Ende anhängen möchten, verwenden Sie ios :: app in der Eröffnungsdatei. Wenn Sie den Inhalt bei jeder Schreiboperation löschen möchten, sollten Sie zwei Dateiströme haben, einen zum Lesen und einen zum Schreiben, so dass der zum Schreiben den Flag ios :: out | verwendet ios :: trunc. weil ios :: trunc im Lese-/Schreibmodus nichts tut.

4 - Wenn Sie wirklich durch Verweis übergeben wollen, dann müssen Sie String-Objekte im Haupt deklarieren, indem Sie ihnen Werte übergeben ("abc" und "12345" für jeden) und dann diese Strings übergeben, um nicht die Werte zu schreiben und zu lesen.

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

class MyFileClass 
{ 
public: 
    MyFileClass( std::string file_name); 
    ~MyFileClass() { m_file.close(); } 
    bool read (std::string content); 
    bool write(std::string data); 
private: 
    std::fstream m_file; 
}; 

MyFileClass::MyFileClass(std::string file_name) 
{ 
    m_file.open(file_name.c_str(), ios::out | ios::in | ios::app); 
    if(!m_file) 
     cout << "Failed to open file!" << endl; 
} 

bool MyFileClass::write(const std::string data) 
{ 
    if (!m_file.fail()) 
    { 
     m_file << data.c_str() << std::flush; 
    } 

    return m_file.fail() ? true : false; 
} 

int main() 
{ 

    std::string sFile = "data.dat"; 

    MyFileClass sample_file(sFile); 

    sample_file.write("123456"); 
    sample_file.write("abc"); 

    return 0; 
} 
+0

Hallo, danke für deinen Kommentar. Es war mein Fehler mit all den Const und so, aber es ist nur eine kleine Stichprobe und überhaupt nicht mit der Hauptfrage verwandt. – mappa

+0

Zufällig drücken Sie die Eingabetaste. Die Antwort in Kürze war ich konnte ich nicht abschneiden und bereits Datei öffnen. Zwei Streams Vorschlag ist keine Option ( – mappa

+0

Wieder ... Okay, so sind Ihre Punkte 1,2,4 alle meine Fehler und es ist nicht das, was ich fragen möchte (nur ein Beispiel, um die Idee zu demonstrieren, Code muss nicht run oder compile) Punkt 3- Ich habe 1 Datei bereits geöffnet und es bleibt offen, das ist die Voraussetzung.Ein weiterer Stream oder öffnen Sie ihn erneut, um den neuen Modus neu zuzuweisen, ist keine Option.Barmars Links beschreiben das Problem und die aktuelle Einschränkung gut genug. – mappa

Verwandte Themen