从控制台 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】:

我的结论是,直接从打印的内容中获取日志是最好的方法,但我在网上找不到任何人询问如何做到这一点。

如今的控制台是终端仿真器。原始终端的输出进入打印机,无法(轻松)读回。

应用程序的stdoutstderr(控制台)流是只写的。此外,在 Windows 和 Unix/Linux 中,您可以将程序的(控制台)输出(stderrstdout 中的一个或两者)通过|(管道)在您的 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++ 获取打印的语句的主要内容,如果未能解决你的问题,请参考以下文章

C++ 流程控制⁽¹⁰⁾|break 语句

Rails 3 - 如何将语句从一个控制器打印到另一个

从应用程序扩展打印到控制台

将日志消息打印到 MotionBuilder

spring集成hibernate 怎样在控制台输出打印建表语句

从 AllocConsole C++ 获取行输入