2016-04-21 37 views
0

我想从标准输入中读取一些数字,处理它们,然后读取下一串数字。从std :: cin读取多次 - 在Linux和Mac OS X上有不同的行为

我想出了解中的EOF字符并清除eofbit,failbit和badbit的解决方案。下面的代码工作在Ubuntu 14.04与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; 
} 

所以,在Ubuntu上我可以输入1<Return>2<Return>^D,得到一些输出,类型3<Return>4<Return>^D,获得更多的产出和程序终止。

在Mac OS 10.10然而,使用相同版本的GCC,该程序将不接受第二轮输入,但打^D后第一时间的两倍数的第一序列输出。

  • 为什么会有不一致的行为?是否有可能解决它?
  • 惯用的接受两次输入的方式是什么?
  • 在我的使用案例中,第一批数字最终可能会从文件或管道中读取。我怎样才能在该场景中交互式地要求额外的输入。
+0

也许尝试调用'的std :: cin.clear()'发送后使用它之前, “EOF”是第一次? – Galik

+0

这是控制台行为,而不是C++代码。在MacOS中,它可能在发送EOF之后关闭输入流[就像在Windows中一样](http://stackoverflow.com/questions/10147996/resume-reading-from-iostreamcin-after-ctrlz-eof-ignore-doesnt-work?rq = 1) –

回答

0

我不是所有熟悉不过了,这家伙也有类似的问题:Signal EOF in mac osx terminal

默认情况下,在开始按下控制d OS X(以前的Mac OS X)终端EOF认识一条线。

具体来说,实际操作是,当按下control-D时,终端输入缓冲区中的所有字节将被发送到使用终端的正在运行的 进程。在一行的开始处,缓冲区中没有字节,因此该过程被告知有零字节可用,并且 这充当EOF指示符。

此过程兼作线的端部之前递送输入到过程 的方法:用户可以键入一些字符,然后按 控制-d,和字符将不立即被发送到过程中, 通常等待输入/返回被按下。在这个 “立即发送所有缓冲的字节”操作被执行之后,没有字节 留在缓冲区中。因此,当第二次按下control-D时,它与一行的开始处相同(不发送字节, 进程为零字节),并且它的行为类似于EOF。

通过在终端中使用命令“man 4 tty”,可以了解有关终端行为的更多信息。默认的线路规程是termios。您可以通过使用命令“man termios”来了解有关termios line纪律的更多信息。

埃里克Postpischil

接受的答案

我没有OSX要测试的,但也许这说明了其行为