阅读文件*(希望是标准的)C ++工具?

时间:2012-12-03 13:46:53

标签: c++ linux

我需要从我的程序中读取另一个程序的输出。为此,我可以使用popen()。这样,我得到一个FILE *到程序的输出,可以在我的程序中解析。如何从程序中读取和解析popen()的返回值的内容?或者,是否有更多类似于C ++的popen版本?

2 个答案:

答案 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;
}