• 分享一个自己项目中用到的c++版的日志类(对初学者十分有用的,有问题的可以留言)


    【注】c++这块的日志类,很容易因为编译环境设置字符集,参数类型等问题带来一些不方便调用的问题。 那么一开始可以在日志中提供宽字节类型的传参处理。否则可能会部分情况下可以,部分情况下会丢失信息。

    Log.h文件内容

    #pragma once
    #include "stdio.h"
    #include "windows.h"
    #include "tchar.h"
    #include "shlwapi.h"
    #pragma comment(lib,"shlwapi.lib")
    class Log
    {
    public:
        //这个WriteByW比较兼容,Write在遇到ansi时有时无法打印出来.
        static bool WriteByW(const wchar_t* logStr, TCHAR* logType = _T("log"), TCHAR * logDir = _T("log"));
        //参数如何区分目录和文件:
        //如果最后有\肯定是目录
        //如果最后又后缀".",则肯定是文件
        //如果最后没有\,也没有后缀'.",则认为是路径
        static bool CreateFolder(TCHAR* pszPath);
    private:
        Log();
        ~Log();
        static Log* InitInstance();
        //当前路径
        static TCHAR s_curPath[MAX_PATH];
        //日志目录
        static TCHAR s_logDir[MAX_PATH];
        //日志的全目录路径
        static TCHAR s_logPath[MAX_PATH];
        static Log* s_instance;
    };

    Log.cpp的文件内容

    /*
       使用示例:
    正常引入头文件 Log::WriteByW(L"调用了日志(byW)"); Log::WriteByW(AnsiToUNICODE(upload_id).c_str());
    */ #include "stdafx.h" #include "Log.h" Log* Log::s_instance = NULL; TCHAR Log::s_curPath[MAX_PATH]; TCHAR Log::s_logPath[MAX_PATH]; TCHAR Log::s_logDir[MAX_PATH]; Log * Log::InitInstance() { if (s_instance == NULL) { s_instance = new Log(); } return s_instance; } bool Log::WriteByW(const wchar_t * logStr, TCHAR * logType, TCHAR * logDir) { wcscpy_s(s_logDir, logDir);//_tcscpy(s_logDir, logDir); InitInstance(); SYSTEMTIME time; GetLocalTime(&time); WCHAR date[128] = { 0 }, filename[128] = { 0 }, hh[50] = _T(" "); swprintf_s(date, _T("%d-%02d-%02d %02d:%02d:%02d"), time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond);//_stprintf swprintf_s(filename, _T("%s\%s_%d-%02d-%02d.log"), s_logPath, logType, time.wYear, time.wMonth, time.wDay);//_stprintf FILE* fp; _tfopen_s(&fp, filename, _T("a,ccs=UTF-8"));//_stprintf WCHAR newstr[1024] = { 0 }; swprintf_s(newstr, _T("%s : %s "), date, logStr); if (fp) { fwrite(newstr, sizeof(WCHAR), _tcslen(newstr), fp); fclose(fp); return true; } else { return false; } } bool Log::CreateFolder(TCHAR* pszPath) { //如果后面有\则是路径,如果没有,但有后缀,则是文件,无后缀则也是路径 TCHAR szPath[_MAX_PATH] = { 0 }; wcsncpy_s(szPath, pszPath, _MAX_PATH);//_tcsncpy szPath[_MAX_PATH - 1] = 0; TCHAR* pdot = _tcsrchr(szPath, _T('.')); TCHAR* psp = _tcsrchr(szPath, _T('\')); if (psp && pdot && pdot > psp) { //在路径最后找到上面两个字符证明是文件,去掉文件名 psp[0] = 0; } else { //缺省是个目录,这个地方可能吧没有后缀的文件当作目录,这里不做处理,默认当成目录 } PathAddBackslash(szPath); if (PathIsDirectory(szPath)) return true; psp = _tcschr(szPath, _T('\')); while (psp) { *psp = 0; if (!PathIsDirectory(szPath)) { if (!CreateDirectory(szPath, 0)) return false; } *psp = _T('\'); psp = _tcschr(psp + 1, _T('\')); } return true; }; Log::Log() { //取当前执行模块的全路径,如果此模块是被其它程序调用的,返回的路径还是这个程序的路径 ::GetModuleFileName(NULL, s_curPath, MAX_PATH); //从路径中移除文件名 PathRemoveFileSpec(s_curPath); swprintf_s(s_logPath, _T("%s\%s"), s_curPath, s_logDir);//_stprintf if (!CreateFolder(s_logPath)) { MessageBox(NULL, _T("日志目录创建失败"), NULL, 0); } } Log::~Log() { }
  • 相关阅读:
    面向对象(二)之三大特性
    面向对象(一)之类和对象
    java基础知识(三)之数组
    Java基础知识(二)之控制语句
    java基础知识(一)之数据类型和运算符
    事件模型
    AWT和布局管理器
    选择器
    颜色值与长度
    排版与缩写
  • 原文地址:https://www.cnblogs.com/taohuadaozhu/p/12934619.html
Copyright © 2020-2023  润新知