它是直线前进使用FILE*
作为底层目的地创建一个数据流缓存器和使用这种数据流缓存器创建相应std::ostream
。它大致看起来是这样的:
#include <stdio.h>
#include <streambuf>
#include <ostream>
class stdiobuf
: public std::streambuf {
enum { bufsize = 2048 };
char buffer[bufsize];
FILE* fp;
int (*close)(FILE*);
int overflow(int c) {
if (c != std::char_traits<char>::eof()) {
*this->pptr() = std::char_traits<char>::to_char_type(c);
this->pbump(1);
}
return this->sync()
? std::char_traits<char>::eof()
: std::char_traits<char>::not_eof(c);
}
int sync() {
std::streamsize size(this->pptr() - this->pbase());
std::streamsize done(this->fp? fwrite(this->pbase(), 1, size, this->fp): 0);
this->setp(this->pbase(), this->epptr());
return size == done? 0: -1;
}
public:
stdiobuf(FILE* fp, int(*close)(FILE*) = fclose)
: fp(fp)
, close(close) {
this->setp(this->buffer, this->buffer + (this->fp? bufsize - 1: 0));
}
~stdiobuf() {
this->sync();
this->fp && this->close(this->fp);
}
};
class opipestream
: private virtual stdiobuf
, public std::ostream {
public:
opipestream(std::string const& pipe)
: stdiobuf(popen(pipe.c_str(), "w"), pclose)
, std::ios(static_cast<std::streambuf*>(this))
, std::ostream(static_cast<std::streambuf*>(this)) {
}
};
int main()
{
opipestream out("/usr/bin/sed -e 's/^/xxxx /'");
out << "Hello\n";
out << "world\n";
}
基本思想是你可以通过实现一个流缓冲区来创建一个新的流。上面的实现应该相当完整。尽管最可能发生错误的情况是管道被关闭,并且没有什么可以做的事情,但是可以改进不完整缓冲区的错误处理。
试着看'boost :: iostreams :: file_descriptor'。它有非常糟糕的文档,但它可以帮助你,它是跨平台的。 – vladon
是否有任何特定原因需要*使用'ostream' –
您可以在创建过程之前将所有输入放入'fileStream'中,然后将其作为输入反馈给'my_prog',或者直接输入一些未知的输入过程创建后? – 1201ProgramAlarm