我需要从我的程序中读取另一个程序的输出。为此,我可以使用 popen()。这样,我得到一个 FILE* 到可以在我的程序中解析的程序输出。如何从我的程序中读取和解析 popen() 返回值的内容?或者,在某处是否有更像 C++ 的 popen 版本?
问问题
207 次
2 回答
3
您可以创建一个流缓冲区做道德等价,popen()
也可以创建一个流缓冲区包装FILE*
。一旦你得到一个流缓冲区,你就可以使用它,std::istream
这似乎是你打算做的。从 a 读取的简单(未经测试的)流缓冲区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';
}
}
于 2012-12-03T13:55:33.713 回答
1
在FILE*
调用stdio_filebuf
(GNU 实现)或stdiobuf
. 我认为这不是一个标准化的东西,但如果你用谷歌搜索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;
}
于 2012-12-03T14:15:36.677 回答