从控制台 C++ 获取打印的语句
Posted
技术标签:
【中文标题】从控制台 C++ 获取打印的语句【英文标题】:Grabbing printed statements from console C++ 【发布时间】:2019-12-02 15:16:41 【问题描述】:我的程序中有两个记录器。一个是我在 gui 中制作的,一个超级复杂但设计得非常好,可以打印到控制台。我正在尝试从漂亮的控制台记录器获取输出到渲染的记录器。我已经在阳光下尝试了一切来让它工作,但我似乎无法弄清楚(由于我对其他记录器(spdlog)的代码缺乏理解。)我的结论是直接从打印的是最好的方法,但我在网上找不到任何人询问如何做到这一点。我已经看到了一些问题,但他们只是发布代码作为答案,并没有真正解释发生了什么。 我的问题:有没有办法从控制台获取打印出来的语句,以及这样做会带来哪些性能问题/并发症。
例如,如果我执行std::cout << "hello!" << std::endl;
或一些 printf 语句,我希望能够在代码中进一步向下抓取“hello!”
【问题讨论】:
为什么?您需要解决的实际问题是什么?为什么需要在程序后期“抓取”旧输出? 至于可能的解决方案(或者更确切地说是解决方法,因为您无法真正“获取”终端或控制台输出),只需在内部保存输出? 如果你有你正在记录的信息......也可以直接在你的 GUI 中显示它,而不是尝试做一些听起来离奇和令人费解的事情? 这个问题可能要简单得多:如何在 GUI 和控制台中显示使用 spdlog 编写的日志? 您可以创建自己的“tee”输出流,将输出写入某处,然后是cout
。在互联网上搜索“c++ cout tee”。
【参考方案1】:
我的结论是,直接从打印的内容中获取日志是最好的方法,但我在网上找不到任何人询问如何做到这一点。
如今的控制台是终端仿真器。原始终端的输出进入打印机,无法(轻松)读回。
应用程序的stdout
和stderr
(控制台)流是只写的。此外,在 Windows 和 Unix/Linux 中,您可以将程序的(控制台)输出(stderr
和 stdout
中的一个或两者)通过|
(管道)在您的 stdout
之间创建管道 IPC 的另一个应用程序中。应用程序和另一个应用程序的stdin
。该 IPC 管道是只写的,您的应用程序可能无法从中读取。
您也许能够访问控制其 Windows 控制台窗口的 Windows cmd.exe
的帧缓冲区的内容,但这不会是您写入 stdout
的数据的逐字字节精确副本,因为escape sequences interpreted by Windows console.
如果stdout
被重定向到一个文件中,您可以重新打开该文件进行阅读,但没有可移植的方式重新打开该文件。
换句话说,没有可移植的方式来读取控制台输出。
我已经尝试了所有方法来让它工作,但我似乎无法弄清楚(由于我对其他记录器(spdlog)的代码缺乏了解。
我敢打赌,您还没有尝试阅读 spdlog
文档,尤其是 logger with multi sinks。接收器是一种输出抽象,其实现可以写入文件、内存或两者。您需要将自己的接收器附加到打印到您的 UI 中的 spdlog
。
从base_sink
派生您的接收器并实现抽象成员函数:
virtual void sink_it_(const details::log_msg &msg) = 0;
打印到UI
,以及,
virtual void flush_() = 0;
什么都不做。
然后将您的接收器类的一个对象附加到该spdlog
。
【讨论】:
以上是关于从控制台 C++ 获取打印的语句的主要内容,如果未能解决你的问题,请参考以下文章