如何知道何时通过 C++ 11 上的终端管道输入?

How to know when there is input through the terminal pipe line on C++ 11?

如何知道 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 标准,而我所爱的 filenoisatty 已经不在了。那么在 C++ 11 上有替代它们的方法吗?

相关主题:

  1. checking data availability before calling std::getline
  2. Why does in_avail() output zero even if the stream has some char?
  3. Error "'fdopen' was not declared" found with g++ 4 that compiled with g++3
  4. stdio.h not standard in C++?
  5. GoogleTest 1.6 with Cygwin 1.7 compile error: 'fileno' was not declared in this scope

问题是,当使用 -std=C++11 编译时,filenoisattystdio.h/cstdlib 上未定义,因为它们是 POSIX 的东西。因此,一种解决方案是使用 -std=GNU++11 而不是 -std=C++11。但是是否可以使用 -std=C++11 编写其他内容进行编译?

我不知道执行此操作的完全可移植的方法。据我所知,标准 C++ 不知道它的输入来自哪里的信息,所以如果你在 posix 系统上工作,你应该只使用 isatty

C++ POSIX Standard

据我所知,没有这样的事情。有一个 C POSIX 库,它是 POSIX 标准的一部分。

So there is an alternative to them on the C++ 11?

标准 C++ 中没有替代方案(在 C++11 之前没有,到目前为止在两者之后都没有)。

您需要依赖 POSIX 才能获得所需的功能。

即使在 POSIX 中,也是 unistd.h 定义了 isatty。您忽略了将其包含在您的程序中。

在 C++17 中,您有 <filesystem> header,它有一个 std::filesystem::status() 函数 returns a file_status object .您可以通过 type() 函数访问它的类型,例如通过结果,并使用快速比较来查看它是否是您预期目标的类型。 一种非常天真的方法是这样的:

auto result {std::filesystem::status(fd)};
if (result.type() == std::filesystem::file_type::character)
{
   // do some stuff in here 
}

其中 fd 是要检查的文件描述符。由于没有额外的检查,以上并不是完整的证明,但如果它是字符类型,它几乎可以肯定等同于终端。 如果你有一个支持 C++17 的编译器,<filesystem> 会非常方便 https://en.cppreference.com/w/cpp/filesystem/file_type

注意:我刚刚开始使用 <filesystem>,所以这里可能遗漏了一些细微差别,欢迎对答案进行任何更新