2016-04-21 6 views
0

Ich möchte einige Zahlen von der Standardeingabe lesen, sie verarbeiten und dann die nächste Reihe von Zahlen lesen.Lesen von std :: cin mehrmals - unterschiedliches Verhalten unter Linux und Mac OS X

Ich kam mit der Lösung zum Lesen der EOF Zeichen in einem char und löschen Sie die Eofbit, Failbit und Badbit. Der folgende Code funktioniert auf Ubuntu 14.04 mit GCC 4.9.2:

#include <iostream> 
#include <vector> 

int main() { 
    std::vector<double> a; 
    std::vector<double>::iterator it; 
    double x; 
    while(std::cin >> x) { 
     a.push_back(x); 
    } 
    std::cout << "First bunch of numbers:" << std::endl; 
    for (it = a.begin(); it != a.end(); ++it) { 
     std::cout << *it << std::endl; 
    } 

    // get crap out of buffer 
    char s; 
    std::cin >> s; 
    std::cin.clear(); 

    // go for it again 
    while (std::cin >> x) { 
     a.push_back(x); 
    } 
    std::cout << "All the numbers:" << std::endl; 
    for (it = a.begin(); it != a.end(); ++it) { 
     std::cout << *it << std::endl; 
    } 

    return 0; 
} 

Also, auf Ubuntu kann ich 1<Return>2<Return>^D geben, eine Ausgabe zu erhalten, geben Sie 3<Return>4<Return>^D, mehr ausgegeben und das Programm beendet erhalten.

Unter Mac OS 10.10 jedoch die gleichen GCC-Version verwenden, das Programm wird die zweite Runde der Eingabe nicht akzeptieren sondern gibt die erste Folge von Zahlen zweimal nach ^D das ersten Mal zu treffen.

  • Warum gibt es inkonsistentes Verhalten? Kann man das umgehen?
  • Was wäre die idiomatische Art und Weise, Eingabe zweimal zu akzeptieren?
  • In meinem Anwendungsfall kann die erste Gruppe von Zahlen möglicherweise aus einer Datei oder Pipeline gelesen werden. Wie kann ich auch in diesem Szenario interaktiv nach zusätzlichen Eingaben fragen?
+0

Vielleicht versuchen 'std :: cin.clear Aufruf()', bevor Sie es nach dem Senden 'EOF' zum ersten Mal? – Galik

+0

Dies ist Konsolenverhalten, nicht C++ - Code. In MacOS schließt es wahrscheinlich den Eingabestrom nach dem Senden von EOF [wie in Windows] (http://stackoverflow.com/questions/10147996/resume-reading-from-iostreamcin-after-ctrlz-eof-ignore-doesnt-work?rq) = 1) –

Antwort

0

im nicht so vertraut, aber dieser Typ eine ähnliche Frage hat: Signal EOF in mac osx terminal

standardmäßig OS X (früher Mac OS X) Terminals erkennen EOF, wenn die Steuer-D am Anfang gedrückt wird einer Linie.

Im Detail ist die tatsächliche Operation, dass, wenn Steuerung D gedrückt wird, alle Bytes im Eingangspuffer des Terminals werden an den laufenden Prozess über das Terminal gesendet. Am Anfang einer Zeile befinden sich keine Bytes in des Puffers, so dass dem Prozess mitgeteilt wird, dass 0 Bytes verfügbar sind, und dies als EOF-Indikator fungiert.

Dieses Verfahren dient auch als ein Verfahren zum Eingang vor dem Ende einer Zeile auf den Prozess zu liefern: Der Benutzer kann einige Zeichen eingeben und Steuer-D drücken, und die Zeichen werden auf den Prozess sofort gesendet werden ohne das übliche warten auf Enter/Return gedrückt zu werden. Nachdem "alle gepufferten Bytes sofort senden" ausgeführt wird, bleiben keine Bytes im Puffer übrig. Wenn also control-D ein zweites Mal gedrückt wird, ist derselbe wie der Anfang einer Zeile (es werden keine Bytes gesendet und der Prozess erhält null Bytes), und es verhält sich wie ein EOF.

Sie können mehr über Terminal-Verhalten lernen, indem Sie den Befehl "man 4 tty" in Terminal verwenden. Die Standardzeilendisziplin ist Termios. Sie können erfahren Sie mehr über die termios Line Disziplin mit dem Befehl "man termios".

akzeptierte Antwort von Eric Postpischil

mir nicht OSX gegen testen, aber vielleicht erklärt dies das Verhalten