komisches verhalten meiner while schleife



  • Nathan schrieb:

    Plattfuss schrieb:

    Reicht es da schon den cin stream zu leeren oder wie würdet ihr das machen?

    Ja.
    std::istream::ignore ist die passende Funktion dafür.

    Sicher das man das so schreibt?

    #include <iostream>
    #include <string>
    using namespace std;
    
    int main(){
    char Eingabe;
    string E2;
    
    cin >> Eingabe; // Dieses Befehl hätte ich gerne ersetzt
    cout << endl << Eingabe;
    // std::istream::ignore;  beides geht nicht
    // std::istream::ignore();
    cin >> E2;
    std::cin.ignore(std::cin.rdbuf()->in_avail());
    cout << endl << E2;
    }
    


  • Plattfuss schrieb:

    Nathan schrieb:

    Plattfuss schrieb:

    Reicht es da schon den cin stream zu leeren oder wie würdet ihr das machen?

    Ja.
    std::istream::ignore ist die passende Funktion dafür.

    Sicher das man das so schreibt?

    Das ist der Name der Funktion.
    std::cin ist vom Typ std::istream und ignore ist eine Memberfunktion von std::istream. Aufruf von Memberfunktionen geschieht mit objekt.name().
    Und nutze nicht in_avail(). Das ist höchst plattformabhängig. Nutze stattdessen std::numeric_limitsstd::streamsize::max(), das ist portable (limits includen dafür).



  • Nathan schrieb:

    Plattfuss schrieb:

    Nathan schrieb:

    Plattfuss schrieb:

    Reicht es da schon den cin stream zu leeren oder wie würdet ihr das machen?

    Ja.
    std::istream::ignore ist die passende Funktion dafür.

    Sicher das man das so schreibt?

    Das ist der Name der Funktion.
    std::cin ist vom Typ std::istream und ignore ist eine Memberfunktion von std::istream. Aufruf von Memberfunktionen geschieht mit objekt.name().
    Und nutze nicht in_avail(). Das ist höchst plattformabhängig. Nutze stattdessen std::numeric_limitsstd::streamsize::max(), das ist portable (limits includen dafür).

    Während ich jetzt kreischend vom Dach springe könnte mir jemand bitte den Code posten wie man das realisiert.



  • #include <limits>
    
    ...
    
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    

    Übersetzung:

    std::cin.ignore(anzahl_zeichen, '\n');
    

    verwirft bis zu anzahl_zeichen Zeichen aus std::cin, hört aber auf, wenn ein '\n'-Zeichen (ein Zeilenumbruch) gefunden wird.

    std::numeric_limits<std::streamsize>::max()
    

    ist der höchste Wert, den std::streamsize annehmen kann. std::streamsize ist ein Alias für einen vorzeichenbehafteten Integertyp (d.h. üblicherweise int oder long), der von deinem Compiler bzw. der zugehörigen Standardbibliothek benutzt wird, um Längen in I/O-Operationen darzustellen.

    In diesem speziellen Zusammenhang wird dieser Wert von ignore als unendlich interpretiert, d. h.

    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    

    bedeutet "verwirf unendlich viele Zeichen aus std::cin, und hör damit auf, wenn du einen Zeilenumbruch findest." Dadurch wird der Rest der Zeile im Eingabepuffer verworfen.



  • Wenns dir nur um nen Zeilenumbruch geht, nimm lieber '\n'.
    Deine arme Festplatte und Geduld, wenn du irgendwann mal millionenweise Werte in ne Datei haust mit endl nach jedem.

    LG



  • hardware schrieb:

    Deine arme Festplatte und Geduld, wenn du irgendwann mal millionenweise Werte in ne Datei haust mit endl nach jedem.

    Die Festplatte stört das nicht, das ganze I/O ist mehrfach gebuffert bis auf dem Weg zur Festplatte. Aber langsam ist das natürlich, wegen den Syscalls.



  • ooh. Und ich dachte immer, wenn man flusht schreibt der das direkt drauf.
    Da sieht man wieder, man lernt nie aus!;)



  • Tut er auch, s. 27.9.1.5 (10) in C++11. Dass 27.9.1.5 (10) relevant ist, ergibt sich aus 27.7.3.7 (7), 27.6.3.2.2 (4) und 27.9.1.5 (19).

    Da muss jetzt nicht notwendigerweise eine Festplatte unter der Datei liegen (kann bspw. auch ne RAM-Disk sein), aber mehrfach gebuffert sind die Dinge höchstens durch Umstände außerhalb deines Programms. Wenn es sich um eine reguläre Datei auf einem Dateisystem auf einer Festplatte handelt, ist davon auszugehen, dass es direkt dahingeschrieben wird, mindestens ins Journal.



  • Bist du sicher dass da ein Flush() der OS Puffer vorgeschrieben ist? Bzw. dass auch vorgeschrieben ist dass das OS den Datenträger anweisen muss seine eigenen Caches zu flushen?



  • Den Festplattencache hätte ich jetzt als Teil der Festplatte aufgefasst. So weit runter spezifiziert der Standard das nicht, weil er von solchen Dingen ja auch nichts weiß. Wenn ich das richtig lese, ist es analog zu fsync gemeint.



  • fsync muss Caches mit flushen.
    (Ausgenommen natürlich die Caches sind batteriegepuffert oder sonstwie "abgesichert".)

    http://linux.die.net/man/2/fsync schrieb:

    fsync() transfers ("flushes") all modified in-core data of (i.e., modified buffer cache pages for) the file referred to by the file descriptor fd to the disk device (or other permanent storage device) so that all changed information can be retrieved even after the system crashed or was rebooted.

    Kannst du mal den Absatz zitieren den du meinst? Bin mir nämlich nicht sicher welche Revision des Standard du meinst. Aus dem was bei mir unter 27.9.1.5 (10) steht konnte ich nicht rauslesen dass hier irgendwas wirklich an die Platte geschickt werden muss.


Anmelden zum Antworten