【问题标题】:Redirecting C++ fstream重定向 C++ fstream
【发布时间】:2009-07-09 14:45:49
【问题描述】:

所以我有一个 C++ 程序,它通常在执行时会将内容写入日志文件。这是使用 fstream 完成的。但是,现在我想包含关闭日志的功能。本质上,我的代码如下所示:

bool isLogging;
fstream* logFilePtr;

在我的代码中,有一堆语句,例如:

(*logFilePtr) << "    Kernel call time in seconds: " << kTime << endl;
...

现在,如果“isLogging”为真,我不想打印这些。我可以用一堆 if 语句包围它们,但我更喜欢比这更干净的东西。我认为有某种方法可以获取 C++ 流并将其重定向到“无”,这样当使用

有谁知道如何重定向流,或者对如何以优雅的方式处理此问题有任何其他想法?

谢谢, 科林

【问题讨论】:

    标签: c++ io stream fstream


    【解决方案1】:

    你可以把它封装在一个类中。

    class Log {
      Log (fstream &s) : stream(s), enabled(false) { }
      void Enable () { enabled = true; }
      void Disable () { enabled = false; }
    
      template<class T>
      Log &operator<< (T const& rhs) {
        if (enabled) stream << rhs;
        return *this;
      }
    
    private:
      fstream &stream;
      bool enabled;
    };
    

    这没有经过测试..但基本的想法应该在那里。

    【讨论】:

      【解决方案2】:

      看看rdbuf member function。您可以创建一个丢弃流缓冲区并将其与您的流相关联。

      struct nullbuf: std::streambuf
      {
          int overflow(int c) { return traits_type::not_eof(c); }
      };
      

      【讨论】:

        【解决方案3】:

        std::iostream 不允许操作系统级别的重定向,但是,您可以在 std::iostreams 之间共享 std::streambufs:

        int main() {
            // redirect stdout to stderr:
            std::streambuf * const oldstdout = std::cout.rdbuf();
            std::cout.rdbuf( std::cerr.rdbuf() );
        
            // test
            std::cout << "Hello ";
            std::cerr << "World" << std::endl;
        
            // re-set, so streambufs are properly deleted:
            std::cout.rdbuf( oldstdout );
        
            // test
            std::cout << "Hello ";
            std::cerr << "World" << std::endl;
        
            return 0;
        }
        

        这样,您可以将日志记录重定向到其他地方(例如“/dev/null”:),或者,如果您遵循 avakar 的回答,请使用 nullbuf。

        【讨论】:

          【解决方案4】:

          平台?如果您在 unix 下,您可以将文件写入 /dev/null

          【讨论】:

          • windows下可以使用nul达到同样的效果
          【解决方案5】:

          我使用 POCO 库的日志记录功能。它支持配置通道 - 控制台,文件,两者。配置输出格式和日志级别(跟踪、调试、错误等)。然后我用诸如

          之类的函数包围日志记录功能
          inline void logError(const std::string & str)
          {
          #ifdef COMPILE_ERROR_LOGGING
             g_pMyPocoLogger->error(str);
          #endif
          }
          

          您可以选择不使用该库,但我仍然建议使用包装器围绕您的日志记录。

          【讨论】:

            【解决方案6】:
            std::ostream& Debug(int level) {
              std::clog.clear(levell <= shown_level ? std::ios_base::goodbit: std::ios_base::badbit);
              return std::clog;
            }
            

            来自comp.lang.c++

            【讨论】:

              【解决方案7】:

              在“关于如何处理此问题的其他想法”下:

              1. 使用状态模式无需对所有代码进行 if 检查。
              2. 将策略模式(编译时策略模式)与 Logging 策略对象结合使用。

              【讨论】:

                猜你喜欢
                • 2012-08-27
                • 1970-01-01
                • 2021-12-04
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多