2012-04-11 2 views
1

Die C++ FAQ over at parashift nutzt etwas ähnlich der folgenden:Warum würde ich istream :: ignore sogar verwenden, wenn ich nach gültigen Eingaben suche?

while (cout << "Enter an integer: " && !(cin >> foo)) 
{ 
    cin.clear(); 

    //feel free to replace this with just (80, '\n') for my point 
    cin.ignore (numeric_limits<streamsize>::max(), '\n'); 
} 

Die cin.ignore (...) scheint jedoch nicht notwendig. Warum kann ich nicht einfach verwenden? Es ist kürzer und benötigt keine Länge. Es ist auch vielseitiger, da es auf die gleiche Weise funktioniert, ob überhaupt Zeichen im Eingabepuffer vorhanden sind oder nicht. Ich habe dies einmal in der gleichen Schleife wie ich mit ignore getestet und es funktioniert auf die gleiche Weise. Es scheint jedoch, dass jedes Beispiel, das diese Art der Eingabevalidierung betrifft, ignore anstelle von sync verwendet.

Was (wenn überhaupt) war der Grund für die Verwendung von ignore, wenn es eine viel einfachere Alternative gibt?

Wenn es darauf ankommt:
Windows-
GCC
MinGW

Antwort

3

Auf einem ifstream ist der Effekt von sync() Implementierung definiert (per C++ 11, §27.9.1.5/19) - es gibt keine Garantie, dass es tun wird, was Sie wollen (und keine echte Garantie dafür) werde ich überhaupt machen. In einem typischen Fall entspricht es ungefähr ignore genau dann, wenn der Stream linepuffered ist - aber wenn der Stream ungepuffert ist, wird er wahrscheinlich nichts tun, und wenn der Stream vollständig gepuffert ist, wird es das tun tue wahrscheinlich schlechte Dinge.

+0

Immer mit der Implementierung definiert, huh. Ich denke, es wäre ein guter Kandidat für diesen Zweck, wenn es nicht wäre. – chris

+1

@chris: Ja, wenn es zuverlässig tun würde, was Sie wollen, wäre es ein guter Kandidat zu tun, was Sie wollen. :-) –

1

Beide verschiedene Dinge tun. sync verwirft bereits gelesene Zeichen, egal wie viele es sind oder was sie sind. Auf der anderen Seite verwirft ignore Zeichen, bis ein bestimmtes Zeichen angetroffen wird, unabhängig davon, ob diese Zeichen bereits gelesen wurden oder ob bereits mehr Zeichen voraus gelesen werden. Stellen Sie sich beispielsweise vor, dass cin über einen 40-Byte-Puffer verfügt, Ihre Zeile jedoch über 80 Byte verfügt. Dann wurden höchstwahrscheinlich die ersten 40 Bytes in den Puffer cin eingelesen. Nachdem Sie den Anfang von denen interpretiert haben, indem Sie sync aufrufen, verwerfen Sie den Rest von diese 40 Zeichen, die Sie bereits gelesen haben, aber nicht die anderen 40 Zeichen in der Zeile. Auf der anderen Seite könnte Ihre Eingabe von einer Pipe kommen, wo normalerweise keine Zeilenpufferung durchgeführt wird. In diesem Fall können Sie nicht nur die aktuelle Zeile, sondern auch Teile der nächsten Zeile, die voraus gelesen wurden, verwerfen. OTOH mit ignore Sie immer sicher wissen, dass Sie immer bis zur nächsten \n lesen (vorausgesetzt, die maximale Anzahl der zu ignorierenden Zeichen ist hoch genug, um darauf zu stoßen).

Verwandte Themen