我需要从我的程序中读取另一个程序的输出。为此,我可以使用popen()。这样,我得到一个FILE *到程序的输出,可以在我的程序中解析。如何从程序中读取和解析popen()的返回值的内容?或者,是否有更多类似于C ++的popen版本?
答案 0 :(得分:3)
您可以创建一个与popen()
相当的流式缓冲区,也可以创建一个包含FILE*
的流缓冲区。获得流缓冲区后,可以将其与std::istream
一起使用,这似乎是您打算做的。从FILE*
读取的简单(和未经测试的)流缓冲区看起来像这样:
struct FILEbuf
: std::streambuf {
FILEbuf(FILE* fp): fp_(fp) {}
int underflow() {
if (this->gptr() == this->egptr()) {
int size = fread(this->buffer_, 1, 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];
};
我认为我错误输入了一些内容,但大致意思确实有效:只需从FILE*
读取到流缓冲区即可。或者,创建从生成的进程读取的流。这需要针对fork()
,exec..()
,pipe()
,close()
,dup2()
进行一些特定于平台的调用(也可能在这里忘记了一些内容)但可以完成同样。
可以使用如上所述的流缓冲器,例如,像这样:
int main()
{
FILEbuf sbuf(fopen("pstream.cpp", "r"));
std::istream in(&sbuf);
for (std::string line; std::getline(in, line); ) {
std::cout << line << '\n';
}
}
答案 1 :(得分:1)
FILE*
上有一个名为stdio_filebuf
(GNU实现)或stdiobuf
的C ++包装器。我认为这不是一个标准化的东西,但如果你谷歌stdiobuf
,你会发现它可以在许多平台上使用。下面是一个工作示例,说明如何将其与FILE*
返回的popen
指针一起使用,使用gcc 4.5.0编译并在Linux机器上进行测试:
#include <ext/stdio_filebuf.h>
#include <stdio.h>
#include <fstream>
#include <string>
#include <iostream>
using namespace std;
int main() {
FILE* f = popen("ls", "r");
__gnu_cxx::stdio_filebuf<char> fdbuf(f, std::ios::in);
std::ifstream in;
in.std::ios::rdbuf(&fdbuf);
string s;
in >> s;
cout << s;
pclose(f);
return 0;
}