"ofstream" - ios::ate



  • Ich hab immer gedacht das beim Modus "ios::trunc" der Dateiinhalt verworfen wird, also:

    ofstream file("D:/text.txt", ios::out | ios::trunc);
    //oder halt nur
    ofstream file("D:/text.txt") //out und trunc sind ja default Werte
    

    So, in meinem Buch steht zum Modus "ios::ate" folgende Definition:

    Einmaliges positionieren des Schreibzeigers an das Dateiende. Schreibzeiger verändert seine Position nur durch manuellen Eingriff.

    Da steht aber ja nix von, das "ios::ate" den Inhalt der jeweiligen Datei verwirft. Weil wenn ich jetzt eine Datei mit:

    ofstream file("D:/text.txt",ios::out | ios::ate);
    

    öffne, dann is der Inhalt FUTSCH!!! Also verwirft "ate" auch den Dateiinhalt?

    MfG
    Stromberg



  • std::ios_base::ate setzt den Positionszeiger(seek) an's Ende der Datei, das ist korrekt. Dabei bleibt der Dateiinhalt erhalten, sonst würde das zusätzliche Flag ja keinen Sinn machen und man könnte direkt std::ios_base::trunc nutzen!!



  • Dann stimmt aber irgendwas bei mir nicht, weil:

    ofstream file("H:/text.txt", ios::out | ios::ate);
    

    löscht bei mir den Dateiinhalt von "H:/text.txt". Warum ist das so? An was kann das liegen?
    MfG
    Stromberg



  • Weiß keiner weiter? Kanns irgendwie an meinem Compiler liegen oder so..? Compiler ist MinGW und IDE Code::blocks.
    MfG
    Stromberg



  • Hallo

    Was genau der Unterschied zwischen trunc und ate ist kann ich auch nicht sagen, das Verhalten deines Codes kann ich jedenfalls nachvollziehen.
    Der richtige Modi den du suchst ist ios::app

    bis bald
    akari



  • Aber das stimmt ja dann nicht so ganz mit der Definition von "ate" überein. z.B. bei http://www.cpp-tutor.de/cpp/le04/le04_03.htm steht auch als Def.:

    Öffnen einer Datei und positionieren des Schreibzeigers auf das Dateiende. Wird der Schreibzeiger neu positioniert (seekp(...)), so werden die Daten an der neuen Position eingefügt.

    Wann nur "app" gehen sollte, was mach ich dann, wenn ich in einer .txt Datei in Zeile "Y" schreiben möchte, aber durch das "app" der Schreibzeiger sowieso immer am Dateiende ist?
    Mh ich bin grad n bissel verwirrt.
    Hast du das mit "ate" auch in deinem Compiler ausprobiert, und is dann auch der Dateiinhalt verschwunden?
    MfG
    Stromberg



  • Stromberg schrieb:

    Dann stimmt aber irgendwas bei mir nicht, weil:

    ofstream file("H:/text.txt", ios::out | ios::ate);
    

    löscht bei mir den Dateiinhalt von "H:/text.txt". Warum ist das so? An was kann das liegen?
    MfG
    Stromberg

    lass mal ios::ate weg und du siehst, dass ios::out alleine denselben effekt bewirkt. das verhalten liegt also einfach an ios::out. kombiniere mit ios::in und dein problem ist verschwunden. (ios::ate hat keinerlei anderen effekt, außer den positionszeiger beim öffnen auf ios::end zu setzen)

    ps. die einzig sinnvolle einsatzmöglichkeit ist dann wohl in der kombination in | out | trunc.



  • Aber "ios::in" wird doch zum lesen von Dateien benutzt hab ich immer gedacht?
    Nicht? Um den Schreibeiger dann einmalig ans Dateiende zu setzen muss ich:
    "ios::out | ios::in | ios::ate" machen? Oder würde nur "ios::ate" reichen? Oder ka....irgendwie sind dann aber alle Stream Tutorials die ich kenne bissel missverstädnlich gemacht!
    MfG
    Stromberg



  • Mh, ich formulier mein Problem mal anderst, was mache ich, wenn ich eine Datei habe mit 5 Zeilen:

    blblblblblblblblblblblblb
    clclclclclclclclclclclclc
    blblblblblblblblblblblbbl
    clclclclclclclclclcclcllc
    blblblblblblblblblblblbbl

    und nach der 3. Zeile reinschreiben möchte. Wie setz ich da dann meinen Schreibzeiger hin, wenn bei mir "ate" ja nicht funktioniert?
    MfG
    Stromberg



  • Naja ist das Problem. Dein OS und C++ sieht Dateien nicht Zeilenweise sondern Zeichenweise. Du kannst halt dir nen Template skip_lines machen (s. Werner Salomon) oder einfach direkt, indem du std::getline 3 mal aufrufst (for-Schleife?!). Normal schiebt man Dateizeiger per seekg/seekp aber das bringt dir dabei nicht soviel 😉



  • Aber ich check nich ganz, warum "ate" bei mir nicht funktioniert, ich hab doch ganz normalen ordinären Compiler (MinGW) und n ganz normales ordinäres XP?Da is doch wo der Wurm drin....oder ist das "normal" das "ate" den Dateiinhalt löscht?
    MfG
    Stromberg



  • Na ja, so funktionierts jetzt (siehe Beitrag von "queer_boy", hab ich grad erst gelesen):
    ios::out | ios::in --> Dateiinhalt wird nicht gelöscht, Schreibzeiger am Dateianfang.
    ios::out | ios::in | ios::ate --> Dateiinhalt wird nicht gelöscht, Schreibzeiger am Dateiende.
    ios::out --> Dateiinhalt wird gelöscht, Schreibzeiger logischerweise am Dateianfang
    ios::out | ios::ate --> Dateiinhalt wird gelöscht, Schreibzeiger logischerweise am Dateianfang
    ios::out | ios::app --> funktioniert ganz normal nach Def.

    Also mich verwundert es total, warum ich "ios::out" mit "ios::in" kombinieren muss, obwohl die ja eigentlich gar nix miteinander zu tun haben?!! In jeder Def. die ich bis jetzt von den Modis gelesen habe, wurde es mir aber anderst erklärt, auch merkwürdig! Ist das jetzt nur bei mir so, oder auch bei euch? Und wenns nur bei mir so sein sollte, dann würde mich interessieren warum, und ob meine .exe Dateien ganz normal auf anderen XP System so laufen wie bei mir, oder nicht, also der Code läuft dann aj sicher anderst im Compiler, aber muss ja nicht unbedingt heißen das die .exe dann auf anderen Pcs nicht geht, die bei mir kompiliert wurde? Fragen über Fragen!
    MfG
    Stromberg



  • die logik dahinter: woher weißt du, dass eine datei nicht leer ist? genau, du musst in sie reinschauen. zum reinschauen verwendet man ios::in. ansonsten hat dein stream gar nicht die "rechte", nachzusehen, ob da schon was ist - und schreibt halt einfach in eine neue datei hinein.



  • Der einfachheit halber, ist es auch möglich statt dem
    ostream ein fstream objekt zu erzeugen und dieses NUR mit
    ios::ate zu initialisieren.

    Sieht dann so aus:

    #include <fstream>
    
    using namespace std;
    
    int main()
    {
    	fstream file("/home/dark-eye/testf.txt", ios::ate);
    	return 0;
    }
    

    Das funktioniert zumindest bei mir und gibt queer_boy recht,
    da fstreams mehr zugriffsmöglichkeiten haben als reine ostreams



  • Danke für eure posts!

    Der einfachheit halber, ist es auch möglich statt dem
    ostream ein fstream objekt zu erzeugen und dieses NUR mit
    ios::ate zu initialisieren.

    Löscht bei mir leider auch den Dateiinhalt. Bei mir funzt nur "ios::out | ios::in | ios::ate".

    die logik dahinter: woher weißt du, dass eine datei nicht leer ist? genau, du musst in sie reinschauen. zum reinschauen verwendet man ios::in. ansonsten hat dein stream gar nicht die "rechte", nachzusehen, ob da schon was ist - und schreibt halt einfach in eine neue datei hinein

    Warum funktioniert dann bei mir aber "ios::out | ios::app"? Da wird der Dateiinhalt nicht gelöscht 😞

    MfG
    Stromberg



  • damit sagst du ja explizit, dass du weißt, dass es die datei schon gibt und etwas in ihr drinsteht (nachlesen dort ist also nicht mehr notwendig)

    aber achtung, das ist sicherlich keine offizielle erklärung, mehr eine eselsbrücke.


Anmelden zum Antworten