【问题标题】:Redirect stdout to ostream将标准输出重定向到 ostream
【发布时间】:2018-09-07 10:51:11
【问题描述】:

是否可以将stdout (NOT cout!) 重定向到流(ostream(不重定向到文件!)

为什么?我正在我的应用程序中集成一个 python 解释器,并希望从 python 代码中捕获print() 调用。

我可以通过使用rdbuf() 以这种方式重定向cout,但是来自python 的printf()print() 没有被重定向,因为它转到stdout 而不是cout

【问题讨论】:

  • 我怀疑我们能否正确回答这个问题,而不需要更多关于你如何处理事情的信息,也不需要看到一些代码。如果是您的解释器,那么您就是执行print 的人,因此您可以将文本发送到任何您喜欢的地方??
  • 您也许可以使用freopen,但不确定。虽然 LRiO 是对的,但你应该负责为你的 python 解释器实现 printf
  • 如何启动这个 python 脚本?我确信可以直接向 python 脚本提供自定义标准输出。
  • 这在很大程度上是一个 A/B 问题。 stackoverflow.com/q/4307187/214671 中解释了您实际问题的解决方案;特别是第二个似乎做得很好。

标签: c++ windows stream stdout


【解决方案1】:

在 Linux 上,您可以在 python 脚本执行期间简单地将 STDOUT 临时重定向到一个临时文件。

在python调用结束时,您可以读取临时文件的内容,然后转储文件。

我很确定 Windows 也会有类似的机制。

这是第一次尝试使用一些 RAII 来清理所有手柄。

#include <unistd.h>
#include <cstdio>
#include <stdlib.h>
#include <string>
#include <iostream>

void simulate_python_script() {
    std::printf("Written to STDOUT I think");
}

struct auto_fd {
    auto_fd(int fd)
            : fd_(fd) {}

    ~auto_fd() {
        if (fd_ != -1)
            ::close(fd_);
    }
    auto_fd(auto_fd const&) = delete;
    auto_fd& operator=(auto_fd const&) = delete;

    operator int() const {
        return fd_;
    }

    int fd_;
};

struct file_closer
{
    void operator()(FILE* p) const noexcept
    {
        ::fclose(p);
    }
};


using auto_fp = std::unique_ptr<FILE, file_closer>;
auto make_auto_fp(FILE* fp)
{
    return auto_fp(fp, file_closer());
}

struct push_fd {
    push_fd(int target, int new_fd)
            : saved_(::dup(target)), target_(target) {
        ::dup2(new_fd, target);
    }

    ~push_fd() {
        if (saved_ != -1) {
            ::dup2(saved_, target_);
            ::close(saved_);
        }
    }

    int saved_, target_;
};

int main() {
    using namespace std::literals;


    auto tempfp = make_auto_fp(::tmpfile());
    auto tempfd = auto_fd(::fileno(tempfp.get()));

    // redirect STDOUT to the temp file with RAII
    {
        push_fd fd_save(1, tempfd);
        simulate_python_script();
    }

    // now read the file which Python thought was STDOUT    
    char buf[256];
    while (auto count = ::read(tempfd, buf, 256)) {
        if (count < 0) break; // error condition
        std::cout.write(buf, count);
    }

    std::cout << std::endl;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-15
    • 1970-01-01
    • 1970-01-01
    • 2012-05-26
    • 2016-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多