C++ Verständnisfrage bei streams



  • Hallo Leute,

    ich hab mir folgenden Code geschrieben:

    std::ofstream outuebergabe("uebergabe.dat", std::ios::out| std::ios::trunc);
    
     if( !outuebergabe.is_open() ) 			//Fehlerprüfung ob Datei geöffnet werden kann
            {
              std::cerr << "Fehler beim Oeffnen der Datei \n";
              return 1;
            }  
    outuebergabe.open("uebergabe.dat");
    outuebergabe << "abort-flag";
    outuebergabe.close();
    

    Warum wird mir nicht "abort-flag" in die Datei geschrieben? Wenn ich die Zeile

    outuebergabe.open("uebergabe.dat");
    

    rausschmeiße wird die Datei beschrieben. Kann mir das bitte jemand erklären. 🙂

    Viele Grüße

    Guddy



  • Lies dir deinen Code nochmal genau durch, dann müsstest dus eigentlcih von selbst erkennen:
    Der konstruktor öffnet bereits die Datei (sonst würdes du in deiner if-verzweigung landen. Was passiert wohl beim Aufruf von open()? - Richtig, es wird versucht, eine offene Datei nochmal zu öffnen.
    Ich rate mal (obs stimmt steht in der Doku): Da das nicht klappt wird ein error-flag gesetzt und die schreibversuche danach schlagen fehl...


  • Administrator

    std::ofstream outuebergabe("uebergabe.dat", std::ios::out| std::ios::trunc);
    Dies öffnet die Datei bereits. Du prüfst ja dann auch, ob sie schon offen ist. Mit der folgenden Anweisung outuebergabe.open("uebergabe.dat"); erzeugst du einen Fehler, weil der Stream die Datei bereits geöffnet hat. Der Stream wird auf einen Fehlerzustand gesetzt und schreibt somit nichts mehr.

    Nimm die Zeile also raus. Macht ja überhaupt gar keinen Sinn, die überhaupt aufzurufen.

    Grüssli

    PS: C++ Referenz (nicht vollständig, aber gut) www.cplusplus.com/reference



  • ja, das leuchtet ein.

    wie mach ich das dann an der Stelle:

    std::ifstream inresult("simresult.dat");     		
         std::string  value;					//Prüfvariable 
           do{
             inresult.open("simresult.dat");
             inresult >> value;
             inresult.close();
             cout << "Prüfe Datei simresult auf Reply-FLag...\n";
           }while(value != "reply-flag");
    

    Es soll solange simresult.dat gelesen werden bis "reply-flag drinsteht. Erzeugt mir aber keinen Fehler...

    Viele Grüße

    Guddy


  • Administrator

    1. Das ist eine ganz schlechte Sache. Du verbrauchst unnötig viel CPU-Zeit um diese Checks durchzuführen. Baue mindestens ein sleep oder was ähnliches ein, um die CPU etwas zu entlasten.
    2. std::ifstream hat auch einen Defaultkonstruktor. Kannst du in der von mir verlinkten Referenz nachschlagen:
    http://www.cplusplus.com/reference/iostream/ifstream/ifstream.html

    Grüssli



  • Also sollte das so aussehen?

    std::ifstream inresult("simresult.dat", ifstream::in,
    ifstream::trunc);     		
         std::string  value;					//Prüfvariable 
           do{
             inresult.open("simresult.dat");
             inresult >> value;
             inresult.close();
             sleep(1);
             cout << "Prüfe Datei simresult auf Reply-FLag...\n";
           }while(value != "reply-flag");
    

    Ich dachte der Konstruktor öffnet schon den stream? Kann es dann nicht PRobleme geben wenn ich den nochmals in der while-schleife öffne?
    Sinn der des Codes ist folgender: Ein anderes Programm schreibt mir in simresult.dat die reply-flag rein. Nun soll mein C++-Programm solange warten bis reply-flag vollständig drin steht.

    Grüße

    Guddy



  • guddy schrieb:

    Sinn der des Codes ist folgender: Ein anderes Programm schreibt mir in simresult.dat die reply-flag rein. Nun soll mein C++-Programm solange warten bis reply-flag vollständig drin steht.

    Das macht man über das Betriebssystem. Das bietet dir eine Möglichkeit an zu erfahren ob eine Datei sich geändert hat.



  • Ja, ich habs schon mit der State()-Funktion versucht die Zeit der letzten Dateiänderung auszulesen. Da hatte ich aber Zugriffsprobleme auf beiden seiten. Anscheinend wird die Zeit der letzten Änderung schon geändert sobald das erste neue Zeichen in die Datei geschrieben wird.

    Ist der o.g. code richtig oder nicht?


  • Administrator

    guddy schrieb:

    Ist der o.g. code richtig oder nicht?

    Nein ... du hast ja auch nichts geändert, ausser dem ersten Konstruktoren noch mehr Argumente zu übergeben, anstatt den Defaultkonstruktor (also der ohne Argumente) aufzurufen.
    Überleg doch mal. Du öffnest die Datei im Konstruktor und öffnest sie dann nochmals in der Schleife? Das kann nicht gut gehen. Öffne also die Datei allenfalls erst in der Schleife.

    Zudem weiss ich nicht, ob du die richtige sleep Funktion aufrufst.

    Und man kann nur sagen, dass dies einfach das falsche Vorgehen ist. Viel besser wäre, wenn du die zwei Programme über das Betriebsystem miteinander kommunizieren lässt. Gibt dafür Pipes oder meiner Meinung nach am einfachsten, über Sockets und den Localhost.

    Grüssli


Log in to reply