如何知道何时通过 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 标准,而我所爱的 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++?
- 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
编写其他内容进行编译?
我不知道执行此操作的完全可移植的方法。据我所知,标准 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>
,所以这里可能遗漏了一些细微差别,欢迎对答案进行任何更新
如何知道 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++?
- 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
编写其他内容进行编译?
我不知道执行此操作的完全可移植的方法。据我所知,标准 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>
,所以这里可能遗漏了一些细微差别,欢迎对答案进行任何更新