【问题标题】:Optionally print to stdout at runtime可选择在运行时打印到标准输出
【发布时间】:2014-12-11 15:12:19
【问题描述】:

我在一个 C++ 程序中有输出,我只想查看是否在运行时指定了“详细”选项。我发现很多方法可以在编译时使用预处理器 #define 语句来控制调试输出,但是除了将每个 cout 包装在 if(verbose) 中之外,我找不到任何在运行时执行此操作的方法。

在伪代码中,我想转换:

if(verbose)
  cout << "Some text: " << variable << endl;
...
if(verbose)
  cout << "Other text: " << var << endl;

进入:

if(verbose)
  //block cout

cout << "Some text: " << variable << endl;
cout << "Other text: " << var << endl;

有没有办法在运行时选择性地重新定义 cout 以便这些行静默不打印任何内容?更好的是一种更灵活的方法,允许某些输出同时阻止其他输出。

【问题讨论】:

  • cout 是字符输出,区别于wcout(宽字符输出)。它不是“控制台”。不要将标准输出与 tty 混为一谈。
  • @WilliamPursell 我不完全理解你所做的区分。这是一个在终端中运行的程序,任何 cout 语句都出现在终端中(我理解为标准输出)。问题应该以“我有 tty 输出...”开头吗?
  • 您的问题涉及“控制台输出”。但是,除非您错误地认为 stdout 是控制台,否则代码中的任何地方都与“控制台”无关。我指出认为 stdout 是控制台是错误的。
  • @jake 这取决于系统。至少在 Unix 和 Windows 下,无论程序在哪里运行,都无法保证std::cout 会进入控制台;两个系统都支持管道和重定向。

标签: c++ stdout


【解决方案1】:

您可以简单地将流对象引用绑定到不同的流,具体取决于verbose

ostream& vout = (verbose? cout : nullstream);

然后将vout 用于所有应该只出现在verbose 时的输出。

当然需要先定义nullstream;这涉及到defining a streambuf derived class

【讨论】:

  • 这看起来正是我所需要的,但我必须消化有关定义 nullstream 的信息。
  • @jake:实际上是James Kanze has answered that(我在写上面的时候没有注意到),并且在 Boost 中还有一个 Ready To Use™ 实现。
【解决方案2】:

我不确定您是否正在编写程序,或者您是否已经有要禁用输出的程序。通常,当您编写带有调试输出的软件时,您会想要创建某种日志记录类来帮助您控制输出发生的时间和输出的位置(例如,到文件、到 stdout、到 stderr 等) .一个简单的例子是:

#include <iostream>

class Logger {

public:
    Logger(bool enabled) : enabled(enabled) { }
    void setEnabled(bool enabled) { this->enabled = enabled; }

    template<typename T> Logger& operator<<(T const& t)
    {
        if (enabled)
            std::cout << t;
        return *this;
    }

    // If you'd like manipulator support (e.g., for std::endl)
    Logger& operator<<(std::ostream& (*manipulator)(std::ostream&))
    {
        if (enabled)
            std::cout << manipulator;
        return *this;
    }

private:
    bool enabled;
};

int main()
{
    Logger log(true);
    log << "Hello, " << "World!" << 123; // Prints Hello, World!123

    log.setEnabled(false);
    log << "Hello, " << "World!" << 123; // Prints nothing
}

或者,您可以像其他人提到的那样重定向 cout,甚至只是简单地将程序的输出重定向到命令行上的 /dev/null:

./myProgram > /dev/null

【讨论】:

  • 感谢您修复 @Cheersandhth.-Alf。当然;看起来不错!只需添加注释说明该部分的用途,以防 OP 或任何新读者不熟悉它。
猜你喜欢
  • 2013-05-01
  • 2012-07-31
  • 1970-01-01
  • 2018-12-25
  • 2018-08-10
  • 1970-01-01
  • 1970-01-01
  • 2012-04-26
  • 1970-01-01
相关资源
最近更新 更多