【发布时间】:2016-10-29 21:03:34
【问题描述】:
在 C++ 11 上如何知道终端管道何时有输入?
我可以这样调用我的程序:
1. ./main solved.txt
2. cat unsolved.txt | ./main
3. cat unsolved.txt | ./main solved.txt
我正在使用它来了解我是否需要在 C POSIX 标准上从管道读取数据:
#include <iostream>
#include <sstream>
#include <stdio.h>
#include <unistd.h>
int main( int argumentsCount, char* argumentsStringList[] )
{
std::stringstream inputedPipeLineString;
if( argumentsCount > 1 )
{
printf( "argumentsStringList[1]: %s", argumentsStringList[ 1 ] );
}
// If it is passed input through the terminal pipe line, get it.
if( !isatty( fileno( stdin ) ) )
{
// Converts the std::fstream "std::cin" to std::stringstream which natively
// supports conversion to string.
inputedPipeLineString << std::cin.rdbuf();
printf( "inputedPipeLineString: %s", inputedPipeLineString.str().c_str() );
}
}
但现在我想使用 C++ 11 标准,而我所爱的 fileno 和 isatty 已经不在了。那么在 C++ 11 上有替代它们的方法吗?
相关话题:
- checking data availability before calling std::getline
- Why does in_avail() output zero even if the stream has some char?
- Error "'fdopen' was not declared" found with g++ 4 that compiled with g++3
- stdio.h not standard in C++?
- error: ‘fileno’ was not declared in this scope
- GoogleTest 1.6 with Cygwin 1.7 compile error: 'fileno' was not declared in this scope
问题是当使用-std=C++11 编译时,fileno 和isatty 在stdio.h/cstdlib 上是未定义的,因为它们是 POSIX 的东西。因此,一种解决方案是使用-std=GNU++11 而不是-std=C++11。但是是否可以使用-std=C++11 编写其他内容进行编译?
【问题讨论】:
-
我知道没有可移植的方式。如果没有命令行参数,我通常会使用管道。
-
POSIX 不会因为 C++11 的出现而消失得无影无踪。
fileno和isatty函数从来都不是 C++ 的一部分。 -
-std=gnu++11 有什么问题?
-
这可能很棘手,但您可以检查
cin是否会使用cin.rdbuf()->in_avail()执行阻塞读取。如果它返回 0,则很可能没有等待读取的输入数据(后续读取不会等待用户输入),因此没有管道,除非用户可以在微秒内写入一些东西,当然。可以看到后续的非阻塞读取具有管道存在的间接证明(或<<<输入)。 -
std::cin.rdbuf()->in_avail()总是返回 0。似乎是 GCC 上的一个错误:gcc.gnu.org/bugzilla/show_bug.cgi?id=24206,但我们几乎让它工作了。