c++ - 如何从 C++ 程序中打开进程并将结果读入 ifstream?

标签 c++ c++11 process fstream ifstream

我正在编写一个将在 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/

相关文章:

c++ - VC++ 使单行文本框在返回键上起作用(模仿按钮)

c++ - 我如何 static_assert 解析为 const& 的值是正确的类型?

c++ - 使用 make_tuple 进行比较

c++ - 旧 .net 项目中 Unresolved external 问题

c++ - 检查鼠标按钮是否在 C++ 中交换

c++ - 为什么不能 "combine with previous declaration specifier"

c++ - 有没有办法在每个启动的新进程上从 Windows 获取事件?

c - 为什么 fork() 返回 errno = 22

emacs - Emacs 中的 Common Lisp Inferior Lisp 缓冲区

c++ - 基于 bool 模板参数的重载