我正在编写一个将在 Unix 环境中运行的 C++11 程序(可移植性不是问题)。目前,我有一个 Makefile 调用两个进程,一个写入文件,第二个从该文件读取。
目标:
mkfifo 我的文件
其他程序 > 我的文件 &
我的程序我的文件
出于各种原因,我想从 my_program 中调用所有这些。看起来 popen
很有前途,因为它调用外部进程并提供我可以读取的 FILE*。但是,我已经编写的现有文件处理代码使用 ifstream:
std::ifstream stream1(argv[1]);
有没有合适的方法将 popen
的 FILE* 连接到 ifstream?除了 popen
之外,还有什么我应该使用的吗?
最佳答案
您可以创建一个从 FILE*
中读取的流缓冲区。显然,您可能需要更改代码以使用 std::istream
以防您在创建流以外的其他地方使用 std::ifstream
但这应该是一个直向前变化。这是一个简单的演示,展示了如何创建相应的流缓冲区以及如何使用它:
#include <cstdio>
#include <iostream>
struct FILEbuf
: std::streambuf {
FILEbuf(FILE* fp): fp_(fp) {}
int underflow() {
if (this->gptr() == this->egptr()) {
int size = fread(this->buffer_, 1, int(s_size), this->fp_);
if (0 < size) {
this->setg(this->buffer_, this->buffer_, this->buffer_ + size);
}
}
return this->gptr() == this->egptr()
? traits_type::eof()
: traits_type::to_int_type(*gptr());
}
FILE* fp_;
enum { s_size = 1024 };
char buffer_[s_size];
};
int main()
{
FILEbuf sbuf(popen("ls -l", "r"));
std::istream in(&sbuf);
for (std::string line; std::getline(in, line); ) {
std::cout << line << '\n';
}
}
过去有人告诉我不要使用 popen()
或 system()
因为这些调用被认为是不安全的:这两个调用都会生成一个 shell可以用来劫持他们的行为。另一种方法是使用文件描述符创建流缓冲区,并使用 pipe()
、dup()
(或其兄弟之一)、close()
、fork()
和 execl()
(或其兄弟之一)直接构建管道。
关于c++ - 如何从 C++ 程序中打开进程并将结果读入 ifstream?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24350608/