c++ - 记录标准输入和标准输出
问题描述
是否有一种(理想情况下简单而优雅的)方式来记录stdin
和stdout
?
请注意,我不打算重定向流。我希望标准流能够保持与其他软件通信的功能,同时还将所有进程间通信写入某个文件。
解决方案
选项1:
正如@PaulR 所建议的那样,您可以使用诸如 tee 之类的外部进程(在 Linux/Mac/Unix 上),或者编写自己的进程以在循环中从 stdin 读取并写入 stdout 和另一个文件。
选项 2:
多年前我用std::basic_ios::rdbuf为std::cout
. 所要做的就是定义一个类(参见std::filebuf
和std::streambuf
):
class tee_buf : public std::filebuf {
public:
// Not an owing pointer
tee_buf(std::streambuf * other_stream)
: m_other_stream(other_stream) {}
void swap( tee_buf& rhs );
// No need to override open/close since we need to manage only the file.
// The open/close calls don't touch the other_stream.
protected:
int_type overflow(int_type c = traits_type::eof()) override;
// The parent calls this->overflow(), but then still need to call
// m_other_stream->sync(). This is problematic since m_other_stream
// gets flushed twice.
int sync() override;
pos_type seekoff( off_type off,
std::ios_base::seekdir dir,
std::ios_base::openmode which) override {
return pos_type(off_type(-1)); // ???
}
pos_type seekpos( pos_type sp,
std::ios_base::openmode which) override {
return pos_type(off_type(-1)); // ???
}
....
这对于密集的 IO 来说更有效,因为它避免了中间人。但在大多数情况下,三通解决方案更简单、更可取。如果性能是一个问题(在大多数情况下不是),那么可以让两个流缓冲区共享一个内存缓冲区。也可以使用异步 IO 并行写入两个流。
内存泄漏的用法:
std::cout.rdbuf(new tee_buf(std::cout.rdbuf());
没有内存泄漏的用法:
编写一个 RAII 类来包含tee_buf
, 以保存原始并设置新的std::cout.rdbuf()
. 破坏后恢复状态std::cout.rdbuf()
。创建此类的单个实例,它将在其构造和销毁时完成脏活。
至于 C 风格stdout
:我不相信有办法覆盖它的行为。最多可以使用缓冲存储器,但这还不足以获得所需的功能。stdout
唯一能做的就是使用类似的tee
解决方案。
推荐阅读
- javascript - 从路由器设置时道具未更新
- module - 如何在 Magento 2.3.3 中覆盖 ImageFactory
- sql - 在 MSSQL 中按一列排序
- artificial-intelligence - 在强化学习代理的训练过程中,累积的情节奖励出现了几次下降
- arrays - 用数字填充空的 Numpy 数组
- perl - 无法提取新行中的 Perl 数据
- arrays - 根据Ruby中的键从数组中删除哈希
- php - 我在 jquery 中的 datepicker 验证有什么解决方案吗
- sql-server - 事务上的 SSIS 表锁定
- ruby-on-rails - Heroku 平台 API gem — NameError: 未初始化的常量 ActiveJobClass::Heroku