cin.rdbuf()->in_avail()



  • hiho ihrs,

    folgendes Beispiel:

    #include <iostream>
    using namespace std;
    
    int main()
    {
        unsigned short int s = 7;
    
        cin >> s;
    
        cout << endl << cin.rdbuf()->in_avail(); // 0
    
        system("pause>nul");
    
        return 0;
    }
    

    Wenn ich nun einen unzulässigen Wert eingebe,
    sei es etwas Alphanumerisches oder eine zu große Zahl,
    wird der Zustand des Streamobjekts doch als fehlerhaft gekennzeichnet,
    und die Eingabe bleibt im Puffer stecken.

    " in_avail " liefert doch die Anzahl der Zeichen, die im Puffer zum Lesen bereit stehen.

    Wieso bekomme ich dann aber als Ausgabe immer 0 ?

    -------------------------------------------------------------------------------------------------------------------------

    [ EDIT ] noch eine Frage:

    #include <iostream>
    using namespace std;
    
    int main()
    {
        unsigned short int s = 7;
    
        cin >> s; // Eingabe: 67890
        cout << endl << cin.fail(); // true
        cin.clear();
        cout << endl << cin.fail(); // false
    
        int i = 3;
        cin >> i; // Porg hält an oO
    
        system("pause>nul");
    
        return 0;
    }
    

    Wieso hält das Programm bei " cin >> i " an, und wartet auf eine Eingabe,
    wo doch noch etwas im Puffer steht (67890) ?

    Wenn ich etwas Alphanumerisches bei " cin >> s " eingebe, hält das Programm doch auch nicht an ... hmmm

    danke euch 🙂


  • Mod

    In avail liefert die Anzahl der Zeichen die noch mindestens im Puffer sind. Die üblichen Implementierungen der Standardstreams liefern da immer eine 0.



  • habe gerade auch noch folgendes gefunden:

    in_avail() : If a read position is available, the member function returns egptr – gptr. Otherwise, it returns showmanyc.

    Implementierung von showmanyc in streambuf:

    virtual streamsize showmanyc() { return 0; }
    

    Demnach kann doch aber

    cin.ignore( cin.rdbuf()->in_avail() );
    

    nie funktionieren...


  • Mod

    Dweb schrieb:

    Demnach kann doch aber

    cin.ignore( cin.rdbuf()->in_avail() );
    

    nie funktionieren...

    Tut es ja auch nicht.



  • Zum Loeschen der noch vorhandenen Zeichen im Eingabepuffer bietet sich folgendes an.

    cin.clear();
    	cin.sync();
    


  • BasicMan01 schrieb:

    Zum Loeschen der noch vorhandenen Zeichen im Eingabepuffer bietet sich folgendes an.

    cin.clear();
    	cin.sync();
    

    joa, aber z.B. bei diesem Beispiel hier muss man den Eingabepuffer nicht leeren, wieso?

    - ich gebe z.B. 987654 ein --> cin.fail() ist true.

    - ich setzte die Zustandflags zurück.

    - das Porgramm wartet dann auf eine Eingabe... wieso steht die 987654 nicht im Puffer 😕

    #include <iostream>
    using namespace std;
    
    int main()
    {
        short int s = 7;
    
        cin >> s; // 987654
    
        cin.clear();
    
        int i = 5;
        cin >> i; // wartet auf Eingabe  :confused: 
    
        system("pause");
    
        return 0;
    }
    


  • Dweb schrieb:

    BasicMan01 schrieb:

    Zum Loeschen der noch vorhandenen Zeichen im Eingabepuffer bietet sich folgendes an.

    cin.clear();
    	cin.sync();
    

    joa, aber z.B. bei diesem Beispiel hier muss man den Eingabepuffer nicht leeren, wieso?

    - ich gebe z.B. 987654 ein --> cin.fail() ist true.

    - ich setzte die Zustandflags zurück.

    - das Porgramm wartet dann auf eine Eingabe... wieso steht die 987654 nicht im Puffer 😕

    #include <iostream>
    using namespace std;
    
    int main()
    {
        short int s = 7;
        
        cin >> s; // 987654
        
        cin.clear();
        
        int i = 5;
        cin >> i; // wartet auf Eingabe  :confused: 
        
        system("pause");
        
        return 0;
    }
    

    basic_istream<...>& operator>> (basic_istream<...>&, charT*) benutzt intern std::num_get::get , und das konsumiert(!) so viele für den gegebenen Typen gültige Zeichen aus dem Stream, wie möglich. Für short int ist alles, wo std::isdigit true zurückgibt ein gültiges Zeichen.

    Das der von Dir übergebene Typ zu klein ist, um den übergebenen Wert zu fassen, bemerkt num_get::get erst, wenn es versucht, den eingelesenen Wert in Deine Variable zu schreiben. Das führt zum Setzen des Fehlerflags. Da zu diesem Zeitpunkt die Zeichen aus dem Stream aber bereits konsumiert wurden, ist es leer. Das liegt wiederum daran, dass streams forward iteratoren benutzen. Was einmal konsumiert wurde, ist futsch.



  • ah ok,

    worin besteht eigentlich der Unterschied zwischen basic_istream und istream ?

    Hierachie :

    ios_base <--- basic_ios <--- basic_istream
    ios_base <--- ios <--- istream

    Laut msdn muss man für basic_istream <istream> inkludieren
    [ http://msdn.microsoft.com/en-us/library/x5507bd0(VS.80).aspx ]

    Wenn ich nun <istream> inkludiere, hab ich dann basic_istream und istream zur Verfügung 😕



  • Dweb schrieb:

    ah ok,

    worin besteht eigentlich der Unterschied zwischen basic_istream und istream ?

    Hierachie :

    ios_base <--- basic_ios <--- basic_istream
    ios_base <--- ios <--- istream

    Laut msdn muss man für basic_istream <istream> inkludieren
    [ http://msdn.microsoft.com/en-us/library/x5507bd0(VS.80).aspx ]

    Wenn ich nun <istream> inkludiere, hab ich dann basic_istream und istream zur Verfügung 😕

    std::basic_istream ist ein Template welches für unterschiedliche Char-Typen ( char , wchar_t oder sonstwas, wofür es passende Character-Traits gibt) geeignet ist. std::istream ist ein typedef mit char als Argument auf std::basic_istream .
    Google ist übrigens Dein Freund...



  • 🙄 hatte nie nach istream in Verbinung mit typedef gegoogelt.

    Aber nun als du's gesagt hast, kam gleich en Treffer 🙂

    typedef basic_istream<char, char_traits<char> > istream
    

    danke dir 😉


Anmelden zum Antworten