2015-05-14 517 views
2

我嘗試寫一個簡單的記錄器,但ofstream寫入十六進制而不是字符到文件。 定義:ofstream寫入十六進制而不是字符*

#pragma once 
#include <iostream> 
#include <fstream> 
#include <string> 
#define LOG Logger::getInstance() 
class Logger 
{ 
public: 
    static Logger m_instance; 
    static Logger &getInstance() 
    { 
     if (m_logfile == nullptr) 
     { 
      m_logfile = new std::ofstream(m_logfile_string.c_str(), 
              std::ofstream::out | std::ofstream::app); 
     } 
     return m_instance; 
    } 

    Logger &operator<<(const std::string &c); 
    Logger &operator<<(const char c[]); 

private: 
    static std::ofstream *m_logfile; 
    static std::string m_logfile_string; 
    Logger() {}; 
    Logger(const Logger &) = delete; 
    Logger(Logger &&other) = delete; 
    Logger &operator=(const Logger &other) = delete; 
    Logger &operator=(Logger &&other) = delete; 

    ~Logger() 
    { 
     if (m_logfile != nullptr) 
      m_logfile->close(); 
    }; 

    std::string currentDateTime() const; 
}; 

Impl。

#include "Logger.h" 
#include <iostream> 
#include <ctime> 

Logger Logger::m_instance; 
std::ofstream *Logger::m_logfile = nullptr; 
std::string Logger::m_logfile_string = "log.txt"; 

Logger &Logger::operator<<(const std::string &c) 
{ 
    this->operator<<(c.c_str()); 
    return *this; 
} 

Logger &Logger::operator<<(const char c[]) 
{ 
    std::cout << currentDateTime() << " - " 
       << c << std::endl; 
    m_logfile->operator<<(c); 
    return *this; 
} 

// Get current date/time, format is YYYY-MM-DD.HH:mm:ss 
std::string Logger::currentDateTime() const 
{ 
    auto now = time(nullptr); 
    struct tm tstruct; 
    char  buf[80]; 
    tstruct = *localtime(&now); 
    strftime(buf, sizeof(buf), "%Y-%m-%d.%X", &tstruct); 

    return buf; 
} 

用法:

#include "Logger.h" 
void main() 
{ 
    LOG << "started"; // Logger::getInstance() << "started"; 
} 

結果: 00007FF696EF3C00log.txt控制檯輸出是正確的。

這裏怎麼回事?

+0

您是否已經嘗試過'Logger&Logger :: operator <<(const char * c)'? –

+0

如果我將方法更改爲const char *,則結果相同 – BennX

+0

它將打印指針而不是字符串的內容。你使用哪個工具鏈和操作系統?似乎在Mac OS X上使用clang和gcc可以正常工作。 – gavinb

回答

3

非成員函數的ostream std::operator<<(...)您使用的iostream成員函數:

m_logfile->operator<<(c); 

沒有成員函數operator<<(char* c),但有是operator<<(void* p),所以指針隱式轉換。請參閱關於ostream的文檔。

運營商爲char*不是類的成員函數:

ostream& operator<< (ostream& os, const char* s); 

在這裏看到:operator<< (ostream)

因此,你需要這樣的代碼:

operator<<(*m_logfile, c); 

或者更清潔:

(*m_logfile) << c; 

測試例如:

#include <iostream> 

int main() { 
    std::cout.operator<<("test"); 
    operator<<(std::cout, "test"); 
    std::cout << "test"; 
} 

打印0x400944testtest

+0

好吧這個確定清除它。沒有想到這裏會發生這種隱式慣例。感謝您的澄清。 – BennX

2

如果您使用的

m_logfile->operator<<(c); 

(*m_logfile)<<c; 

相反,它會工作。

原因:

  • 你的語法調用它不是爲char*,也不是string定義的成員函數ostream::operator<<()。它只定義爲void*,它總是以十六進制顯示地址。
  • 經典的語法要求在這裏具有重載stringchar*
相關問題