【问题标题】:Redirecting ostream to file not working将ostream重定向到文件不起作用
【发布时间】:2010-07-06 19:12:02
【问题描述】:

我有一个自定义日志系统,它允许我根据当前选择的详细程度将信息发送到日志文件和控制台。现在,我遇到的问题是文件的输出,控制台的输出工作正常。

这是一个例子:

     ilra_talk << "Local IP: " << systemIP() << " |  Hostname: " << systemhostname() << endl;
     // the systemIP() and systemhostname() functions have already been defined

这应该会导致系统的当前本地 IP 和主机名被打印到文件中。然而,它只会导致信息被打印到控制台,尽管函数是如何重载导致它打印到两者的。

我已经概述了下面的代码。感谢任何帮助(一如既往)。

当前存在 ilra_talk 的定义,这会导致创建新的类对象:

#define ilra_talk ilra(__FUNCTION__,0)

类定义如下:

class ilra
{
    static int ilralevel_set; // properly initialized in my main .cpp
    static int ilralevel_passed; // properly initialized in my main .cpp
    static bool relay_enabled; // properly initialized in my main .cpp
    static bool log_enabled; // properly initialized in my main .cpp
    static ofstream logfile; // properly initialized in my main .cpp
public:
    // constructor / destructor
    ilra(const std::string &funcName, int toset)
    {
        ilralevel_passed = toset;
    }
    ~ilra(){};

    // enable / disable irla functions
    static void ilra_verbose_level(int toset){
        ilralevel_set = toset;
    }
    static void ilra_log_enabled(bool toset){
        log_enabled = toset;

        if (log_enabled == true){
            // get current time
            time_t rawtime;
            time ( &rawtime );

            // name of log file (based on time of application start)
            stringstream logname_s;
            string logname = "rclient-";
            logname_s << rawtime;
            logname.append(logname_s.str());

            // open a log file
            logfile.open(logname.c_str());
        }
    }

    // output
    template <class T>
    ilra &operator<<(const T &v)
    {
        if(log_enabled == true){ // log_enabled is set to true
            logfile << v; 
            logfile << "Test" << endl;  // test will show up, but intended information will not appear
            }
        if(ilralevel_passed <= ilralevel_set)
            std::cout << v;
        return *this;
    }

    ilra &operator<<(std::ostream&(*f)(std::ostream&))
    {
        if(log_enabled == true) // log_enabled is set to true
            logfile << *f;
        if(ilralevel_passed <= ilralevel_set)
            std::cout << *f;
        return *this;
    }
};  // end of the class

【问题讨论】:

  • 日志文件输出是什么样的?控制台输出是什么样的?
  • @Adam 除了我为确保日志文件设置正确而添加的“测试”语句外​​,日志输出不会显示任何内容。控制台会显示这个(针对上面的特定语句):本地 IP:192.168.144.128 |主机名:localhost.localdomain

标签: c++ logging file-io operator-overloading


【解决方案1】:

我认为代码没有完全错误,但我个人会进行两处更改:

  1. 将 logfile.flush() 放入 ilra::~ilra()。记录和缓冲不是朋友。

  2. static ofstream logfile 更改为static ofstream *logfile:在ilra_log_enabled() 中分配/删除它,并在

总的来说,由于日志记录是一种性能消耗,我从不使用 iostreams 并坚持使用类似 printf() 的宏:日志检查是在没有函数调用的情况下进行的,就在宏中。这具有重要的副作用:如果不需要记录,则根本不会评估参数列表。在您的情况下,不可能避免调用函数,例如systemIP()systemhostname(),因为日志级别/等的检查是在它们已经被调用之后完成的。例如,使用宏,我还可以从发布版本中完全删除调试级别的日志记录(或推论:在调试版本中,我可以拥有尽可能多的日志记录)。

【讨论】:

  • 你是对的——代码没有任何问题。只是在文本文件的顶部创建了大量空白,导致实际内容被移动到底部。你有 printf 宏的例子吗?
  • @BSchlinker:……嗯……评论格式很烂。无论如何,这里是 GCC 可变参数宏文档的链接 - gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html - 了解在其他编译器中寻找什么
【解决方案2】:

看起来“测试”很可能是从其他地方打印出来的,实际上log_enabled 并未在您将数据插入流中时设置。您是否尝试过无条件地将数据插入到logfile 流中,或者每次调用operator&lt;&lt; 时打印出log_enabled

或者,cout 的类型为 ostreamlogfile 的类型为 ofstream。是否有可能您的转发操纵器功能没有为ofstream 工作?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-17
    • 2012-11-08
    • 1970-01-01
    • 1970-01-01
    • 2016-02-19
    相关资源
    最近更新 更多