将popen()输出写入文件

时间:2011-01-20 10:23:57

标签: c++ system popen

我一直试图从c ++调用另一个程序,并将该程序的粗壮程序保存到文本文件中。 popen()似乎是适当的功能,但将其保存到文本文件是行不通的。

      ofstream delaunayfile;
    delaunayfile.open ("triangulation/delaunayedpoints.txt");
      FILE *fp;
      fp = popen("qdelaunay < triangulation/rawpoints.txt", "r");
    delaunayfile << fp;
    delaunayfile.close();

有任何帮助吗?提前谢谢!

3 个答案:

答案 0 :(得分:2)

您无法直接将FILE*写入流中。它将写入一个内存地址而不是实际的文件内容,因此它不会给你想要的结果。

理想的解决方案是从ifstream读取并写入ofstream,但无法从ifstream构建FILE*

但是,我们可以扩展streambuf类,使其适用于FILE*,然后将其传递给istream。快速搜索显示有人已经实现了这一点,并正确命名为popen_streambuf。请参阅this specific answer

您的代码将如下所示:

std::ofstream output("triangulation/delaunayedpoints.txt");
popen_streambuf popen_buf;
if (popen_buf.open("qdelaunay < triangulation/rawpoints.txt", "r") == NULL) {
    std::cerr << "Failed to popen." << std::endl;
    return;
}
char buffer[256];
std::istream input(&popen_buf);
while (input.read(buffer, 256)) {
    output << buffer;
}
output.close();

正如评论中Simon Richter指出的那样,operator<<接受streambuf并将数据写入ostream,直到达到EOF。这样,代码将简化为:

std::ofstream output("triangulation/delaunayedpoints.txt");
popen_streambuf popen_buf;
if (popen_buf.open("qdelaunay < triangulation/rawpoints.txt", "r") == NULL) {
    std::cerr << "Failed to popen." << std::endl;
    return;
}
output << &popen_buf;
output.close();

答案 1 :(得分:0)

有两种方法可以做到这一点:简单方法

int rc = system("qdelaunay < triangulation/rawpoints.txt >triangulation/delaunayedpoints.txt");

以及更精细的方式,使用fork(),dup2()和execve(),后者在没有安装shell解释器的情况下工作。鉴于这看起来你正在进行计算工作,我怀疑这不是一个嵌入式系统,所以你可以假设一个工作shell。

答案 2 :(得分:0)

popen打开一个管道,但我不知道你可以通过这种方式将它流式传输到delaunayfile。

当然,如果你能做到这一点会非常好,它会从管道中读取,直到它完成。

检查管道数据的常规方法是使用select()。我找到了一个有用的链接http://codenewbie.com/forums/threads/2908-Using-std-fstream-in-a-pipe,它将管道与fstream集成在一起,它可以帮助你达到你想要的效果。

在这种情况下,虽然您想要做的就是将输出写入文件,为什么不将进程的输出重定向到它而不是管道?管道的目的是进程间通信,但是您的进程似乎没有使用从其他进程接收的数据用于任何实际目的。