baihongyu.com
博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++轻量级日志类CLogger的使用(更新)
阅读量:
4299 次
发布时间:
2019-05-27
本文共 16737 字,大约阅读时间需要 55 分钟。
//logger.h
/*
//类名:CLogger
//功能介绍:Win平台日志记录功能,多线程安全,支持写日志级别的设置,日志格式包含日志等级,日志时间,文件名,行号信息
//作者:sunflover 2016-1-15 14:31:27
//使用方法:
1:将logger.h,logger.cpp添加到项目中
2:设置logger.cpp的预编译头选项为“不使用预编译头”
3:使用代码示例:
#include "Logger.h"
using namespace LOGGER;
CLogger logger(LogLevel_Info,CLogger::GetAppPathA().append("log\\"));
void main()
{
logger.TraceFatal("TraceFatal %d", 1);
logger.TraceError("TraceError %s", "sun");
logger.TraceWarning("TraceWarning");
logger.TraceInfo("TraceInfo");
logger.ChangeLogLevel(LOGGER::LogLevel_Error);
logger.TraceFatal("TraceFatal %d", 2);
logger.TraceError("TraceError %s", "sun2");
logger.TraceWarning("TraceWarning");
logger.TraceInfo("TraceInfo");
}
执行结果:20160126_101329.log文件内容如下
Fatal 2016-01-26 10:13:29 TraceFatal 1
Error 2016-01-26 10:13:29 TraceError sun
Warning 2016-01-26 10:13:29 TraceWarning
Info 2016-01-26 10:13:29 TraceInfo
Fatal 2016-01-26 10:13:29 TraceFatal 2
Error 2016-01-26 10:13:29 TraceError sun2
*/
#
ifndef
_LOGGER_H_
#
define
_LOGGER_H_
#
include
<Windows.h>
#
include
<stdio.h>
#
include
<string>
namespace
LOGGER
{
//日志级别的提示信息
static
const
std
::
string
strFatalPrefix =
"Fatal\t"
;
static
const
std
::
string
strErrorPrefix =
"Error\t"
;
static
const
std
::
string
strWarningPrefix =
"Warning\t"
;
static
const
std
::
string
strInfoPrefix =
"Info\t"
;
//日志级别枚举
typedef
enum
EnumLogLevel
{
LogLevel_Stop =
0
,
//什么都不记录
LogLevel_Fatal,
//只记录严重错误
LogLevel_Error,
//记录严重错误,普通错误
LogLevel_Warning,
//记录严重错误,普通错误,警告
LogLevel_Info
//记录严重错误,普通错误,警告,提示信息(也就是全部记录)
};
class
CLogger
{
public
:
//nLogLevel:日志记录的等级,可空
//strLogPath:日志目录,可空
//strLogName:日志名称,可空
CLogger(EnumLogLevel nLogLevel = EnumLogLevel::LogLevel_Info,
const
std
::
string
strLogPath =
""
,
const
std
::
string
strLogName =
""
);
//析构函数
virtual
~CLogger();
public
:
//写严重错误信息
void
TraceFatal
(
const
char
*lpcszFormat, ...)
;
//写错误信息
void
TraceError
(
const
char
*lpcszFormat, ...)
;
//写警告信息
void
TraceWarning
(
const
char
*lpcszFormat, ...)
;
//写提示信息
void
TraceInfo
(
const
char
*lpcszFormat, ...)
;
//改变写日志级别
void
ChangeLogLevel
(EnumLogLevel nLevel)
;
//获取程序运行路径
static
std
::
string
GetAppPathA
()
;
//格式化字符串
static
std
::
string
FormatString
(
const
char
*lpcszFormat, ...)
;
private
:
//写文件操作
void
Trace
(
const
std
::
string
&strLog)
;
//获取当前系统时间
std
::
string
GetTime
()
;
//文件全路径得到文件名
const
char
*
path_file
(
const
char
*path,
char
splitter)
;
private
:
//写日志文件流
FILE * m_pFileStream;
//写日志级别
EnumLogLevel m_nLogLevel;
//日志目录
std
::
string
m_strLogPath;
//日志的名称
std
::
string
m_strLogName;
//日志文件全路径
std
::
string
m_strLogFilePath;
//线程同步的临界区变量
CRITICAL_SECTION m_cs;
};
}
#
endif
//logger.cpp
#
include
"logger.h"
#
include
<time.h>
#
include
<stdarg.h>
#
include
<direct.h>
#
include
<vector>
#
include
<Dbghelp.h>
#
pragma
comment(lib,
"Dbghelp.lib"
)
using
std
::
string
;
using
std
::
vector
;
namespace
LOGGER
{
CLogger::CLogger(EnumLogLevel nLogLevel,
const
std
::
string
strLogPath,
const
std
::
string
strLogName)
:m_nLogLevel(nLogLevel),
m_strLogPath(strLogPath),
m_strLogName(strLogName)
{
//初始化
m_pFileStream =
NULL
;
if
(m_strLogPath.empty())
{
m_strLogPath = GetAppPathA();
}
if
(m_strLogPath[m_strLogPath.length()
-1
] !=
'\\'
)
{
m_strLogPath.append(
"\\"
);
}
//创建文件夹
MakeSureDirectoryPathExists(m_strLogPath.c_str());
//创建日志文件
if
(m_strLogName.empty())
{
time_t
curTime;
time(&curTime);
tm tm1;
localtime_s(&tm1, &curTime);
//日志的名称如:201601012130.log
m_strLogName = FormatString(
"%04d%02d%02d_%02d%02d%02d.log"
, tm1.tm_year +
1900
, tm1.tm_mon +
1
, tm1.tm_mday, tm1.tm_hour, tm1.tm_min, tm1.tm_sec);
}
m_strLogFilePath = m_strLogPath.append(m_strLogName);
//以追加的方式打开文件流
fopen_s(&m_pFileStream, m_strLogFilePath.c_str(),
"a+"
);
InitializeCriticalSection(&m_cs);
}
//析构函数
CLogger::~CLogger()
{
//释放临界区
DeleteCriticalSection(&m_cs);
//关闭文件流
if
(m_pFileStream)
{
fclose(m_pFileStream);
m_pFileStream =
NULL
;
}
}
//文件全路径得到文件名
const
char
*CLogger::path_file(
const
char
*path,
char
splitter)
{
return
strrchr
(path, splitter) ?
strrchr
(path, splitter) +
1
: path;
}
//写严重错误信息
void
CLogger::TraceFatal(
const
char
*lpcszFormat, ...)
{
//判断当前的写日志级别
if
(EnumLogLevel::LogLevel_Fatal > m_nLogLevel)
return
;
string
strResult;
if
(
NULL
!= lpcszFormat)
{
va_list marker =
NULL
;
va_start(marker, lpcszFormat);
//初始化变量参数
size_t
nLength = _vscprintf(lpcszFormat, marker) +
1
;
//获取格式化字符串长度
std
::
vector
<
char
> vBuffer(nLength,
'\0'
);
//创建用于存储格式化字符串的字符数组
int
nWritten = _vsnprintf_s(&vBuffer[
0
], vBuffer.size(), nLength, lpcszFormat, marker);
if
(nWritten >
0
)
{
strResult = &vBuffer[
0
];
}
va_end(marker);
//重置变量参数
}
if
(strResult.empty())
{
return
;
}
string
strLog = strFatalPrefix;
strLog.append(GetTime()).append(strResult);
//写日志文件
Trace(strLog);
}
//写错误信息
void
CLogger::TraceError(
const
char
*lpcszFormat, ...)
{
//判断当前的写日志级别
if
(EnumLogLevel::LogLevel_Error > m_nLogLevel)
return
;
string
strResult;
if
(
NULL
!= lpcszFormat)
{
va_list marker =
NULL
;
va_start(marker, lpcszFormat);
//初始化变量参数
size_t
nLength = _vscprintf(lpcszFormat, marker) +
1
;
//获取格式化字符串长度
std
::
vector
<
char
> vBuffer(nLength,
'\0'
);
//创建用于存储格式化字符串的字符数组
int
nWritten = _vsnprintf_s(&vBuffer[
0
], vBuffer.size(), nLength, lpcszFormat, marker);
if
(nWritten >
0
)
{
strResult = &vBuffer[
0
];
}
va_end(marker);
//重置变量参数
}
if
(strResult.empty())
{
return
;
}
string
strLog = strErrorPrefix;
strLog.append(GetTime()).append(strResult);
//写日志文件
Trace(strLog);
}
//写警告信息
void
CLogger::TraceWarning(
const
char
*lpcszFormat, ...)
{
//判断当前的写日志级别
if
(EnumLogLevel::LogLevel_Warning > m_nLogLevel)
return
;
string
strResult;
if
(
NULL
!= lpcszFormat)
{
va_list marker =
NULL
;
va_start(marker, lpcszFormat);
//初始化变量参数
size_t
nLength = _vscprintf(lpcszFormat, marker) +
1
;
//获取格式化字符串长度
std
::
vector
<
char
> vBuffer(nLength,
'\0'
);
//创建用于存储格式化字符串的字符数组
int
nWritten = _vsnprintf_s(&vBuffer[
0
], vBuffer.size(), nLength, lpcszFormat, marker);
if
(nWritten >
0
)
{
strResult = &vBuffer[
0
];
}
va_end(marker);
//重置变量参数
}
if
(strResult.empty())
{
return
;
}
string
strLog = strWarningPrefix;
strLog.append(GetTime()).append(strResult);
//写日志文件
Trace(strLog);
}
//写一般信息
void
CLogger::TraceInfo(
const
char
*lpcszFormat, ...)
{
//判断当前的写日志级别
if
(EnumLogLevel::LogLevel_Info > m_nLogLevel)
return
;
string
strResult;
if
(
NULL
!= lpcszFormat)
{
va_list marker =
NULL
;
va_start(marker, lpcszFormat);
//初始化变量参数
size_t
nLength = _vscprintf(lpcszFormat, marker) +
1
;
//获取格式化字符串长度
std
::
vector
<
char
> vBuffer(nLength,
'\0'
);
//创建用于存储格式化字符串的字符数组
int
nWritten = _vsnprintf_s(&vBuffer[
0
], vBuffer.size(), nLength, lpcszFormat, marker);
if
(nWritten >
0
)
{
strResult = &vBuffer[
0
];
}
va_end(marker);
//重置变量参数
}
if
(strResult.empty())
{
return
;
}
string
strLog = strInfoPrefix;
strLog.append(GetTime()).append(strResult);
//写日志文件
Trace(strLog);
}
//获取系统当前时间
string
CLogger::GetTime()
{
time_t
curTime;
time(&curTime);
tm tm1;
localtime_s(&tm1, &curTime);
//2016-01-01 21:30:00
string
strTime = FormatString(
"%04d-%02d-%02d %02d:%02d:%02d "
, tm1.tm_year +
1900
, tm1.tm_mon +
1
, tm1.tm_mday, tm1.tm_hour, tm1.tm_min, tm1.tm_sec);
return
strTime;
}
//改变写日志级别
void
CLogger::ChangeLogLevel(EnumLogLevel nLevel)
{
m_nLogLevel = nLevel;
}
//写文件操作
void
CLogger::Trace(
const
string
&strLog)
{
try
{
//进入临界区
EnterCriticalSection(&m_cs);
//若文件流没有打开,则重新打开
if
(
NULL
== m_pFileStream)
{
fopen_s(&m_pFileStream, m_strLogFilePath.c_str(),
"a+"
);
if
(!m_pFileStream)
{
return
;
}
}
//写日志信息到文件流
fprintf
(m_pFileStream,
"%s\n"
, strLog.c_str());
fflush(m_pFileStream);
//离开临界区
LeaveCriticalSection(&m_cs);
}
//若发生异常,则先离开临界区,防止死锁
catch
(...)
{
LeaveCriticalSection(&m_cs);
}
}
string
CLogger::GetAppPathA()
{
char
szFilePath[MAX_PATH] = {
0
}, szDrive[MAX_PATH] = {
0
}, szDir[MAX_PATH] = {
0
}, szFileName[MAX_PATH] = {
0
}, szExt[MAX_PATH] = {
0
};
GetModuleFileNameA(
NULL
, szFilePath,
sizeof
(szFilePath));
_splitpath_s(szFilePath, szDrive, szDir, szFileName, szExt);
string
str
(szDrive)
;
str.append(szDir);
return
str;
}
string
CLogger::FormatString(
const
char
*lpcszFormat, ...)
{
string
strResult;
if
(
NULL
!= lpcszFormat)
{
va_list marker =
NULL
;
va_start(marker, lpcszFormat);
//初始化变量参数
size_t
nLength = _vscprintf(lpcszFormat, marker) +
1
;
//获取格式化字符串长度
std
::
vector
<
char
> vBuffer(nLength,
'\0'
);
//创建用于存储格式化字符串的字符数组
int
nWritten = _vsnprintf_s(&vBuffer[
0
], vBuffer.size(), nLength, lpcszFormat, marker);
if
(nWritten >
0
)
{
strResult = &vBuffer[
0
];
}
va_end(marker);
//重置变量参数
}
return
strResult;
}
}
有图有真相:
版权声明:本文为博主原创文章,转载请注明原帖地址。 https://blog.csdn.net/sunflover454/article/details/49758801
//logger.h
/*
//类名:CLogger
//功能介绍:Win平台日志记录功能,多线程安全,支持写日志级别的设置,日志格式包含日志等级,日志时间,文件名,行号信息
//作者:sunflover 2016-1-15 14:31:27
//使用方法:
1:将logger.h,logger.cpp添加到项目中
2:设置logger.cpp的预编译头选项为“不使用预编译头”
3:使用代码示例:
#include "Logger.h"
using namespace LOGGER;
CLogger logger(LogLevel_Info,CLogger::GetAppPathA().append("log\\"));
void main()
{
logger.TraceFatal("TraceFatal %d", 1);
logger.TraceError("TraceError %s", "sun");
logger.TraceWarning("TraceWarning");
logger.TraceInfo("TraceInfo");
logger.ChangeLogLevel(LOGGER::LogLevel_Error);
logger.TraceFatal("TraceFatal %d", 2);
logger.TraceError("TraceError %s", "sun2");
logger.TraceWarning("TraceWarning");
logger.TraceInfo("TraceInfo");
}
执行结果:20160126_101329.log文件内容如下
Fatal 2016-01-26 10:13:29 TraceFatal 1
Error 2016-01-26 10:13:29 TraceError sun
Warning 2016-01-26 10:13:29 TraceWarning
Info 2016-01-26 10:13:29 TraceInfo
Fatal 2016-01-26 10:13:29 TraceFatal 2
Error 2016-01-26 10:13:29 TraceError sun2
*/
#
ifndef
_LOGGER_H_
#
define
_LOGGER_H_
#
include
<Windows.h>
#
include
<stdio.h>
#
include
<string>
namespace
LOGGER
{
//日志级别的提示信息
static
const
std
::
string
strFatalPrefix =
"Fatal\t"
;
static
const
std
::
string
strErrorPrefix =
"Error\t"
;
static
const
std
::
string
strWarningPrefix =
"Warning\t"
;
static
const
std
::
string
strInfoPrefix =
"Info\t"
;
//日志级别枚举
typedef
enum
EnumLogLevel
{
LogLevel_Stop =
0
,
//什么都不记录
LogLevel_Fatal,
//只记录严重错误
LogLevel_Error,
//记录严重错误,普通错误
LogLevel_Warning,
//记录严重错误,普通错误,警告
LogLevel_Info
//记录严重错误,普通错误,警告,提示信息(也就是全部记录)
};
class
CLogger
{
public
:
//nLogLevel:日志记录的等级,可空
//strLogPath:日志目录,可空
//strLogName:日志名称,可空
CLogger(EnumLogLevel nLogLevel = EnumLogLevel::LogLevel_Info,
const
std
::
string
strLogPath =
""
,
const
std
::
string
strLogName =
""
);
//析构函数
virtual
~CLogger();
public
:
//写严重错误信息
void
TraceFatal
(
const
char
*lpcszFormat, ...)
;
//写错误信息
void
TraceError
(
const
char
*lpcszFormat, ...)
;
//写警告信息
void
TraceWarning
(
const
char
*lpcszFormat, ...)
;
//写提示信息
void
TraceInfo
(
const
char
*lpcszFormat, ...)
;
//改变写日志级别
void
ChangeLogLevel
(EnumLogLevel nLevel)
;
//获取程序运行路径
static
std
::
string
GetAppPathA
()
;
//格式化字符串
static
std
::
string
FormatString
(
const
char
*lpcszFormat, ...)
;
private
:
//写文件操作
void
Trace
(
const
std
::
string
&strLog)
;
//获取当前系统时间
std
::
string
GetTime
()
;
//文件全路径得到文件名
const
char
*
path_file
(
const
char
*path,
char
splitter)
;
private
:
//写日志文件流
FILE * m_pFileStream;
//写日志级别
EnumLogLevel m_nLogLevel;
//日志目录
std
::
string
m_strLogPath;
//日志的名称
std
::
string
m_strLogName;
//日志文件全路径
std
::
string
m_strLogFilePath;
//线程同步的临界区变量
CRITICAL_SECTION m_cs;
};
}
#
endif
//logger.cpp
#
include
"logger.h"
#
include
<time.h>
#
include
<stdarg.h>
#
include
<direct.h>
#
include
<vector>
#
include
<Dbghelp.h>
#
pragma
comment(lib,
"Dbghelp.lib"
)
using
std
::
string
;
using
std
::
vector
;
namespace
LOGGER
{
CLogger::CLogger(EnumLogLevel nLogLevel,
const
std
::
string
strLogPath,
const
std
::
string
strLogName)
:m_nLogLevel(nLogLevel),
m_strLogPath(strLogPath),
m_strLogName(strLogName)
{
//初始化
m_pFileStream =
NULL
;
if
(m_strLogPath.empty())
{
m_strLogPath = GetAppPathA();
}
if
(m_strLogPath[m_strLogPath.length()
-1
] !=
'\\'
)
{
m_strLogPath.append(
"\\"
);
}
//创建文件夹
MakeSureDirectoryPathExists(m_strLogPath.c_str());
//创建日志文件
if
(m_strLogName.empty())
{
time_t
curTime;
time(&curTime);
tm tm1;
localtime_s(&tm1, &curTime);
//日志的名称如:201601012130.log
m_strLogName = FormatString(
"%04d%02d%02d_%02d%02d%02d.log"
, tm1.tm_year +
1900
, tm1.tm_mon +
1
, tm1.tm_mday, tm1.tm_hour, tm1.tm_min, tm1.tm_sec);
}
m_strLogFilePath = m_strLogPath.append(m_strLogName);
//以追加的方式打开文件流
fopen_s(&m_pFileStream, m_strLogFilePath.c_str(),
"a+"
);
InitializeCriticalSection(&m_cs);
}
//析构函数
CLogger::~CLogger()
{
//释放临界区
DeleteCriticalSection(&m_cs);
//关闭文件流
if
(m_pFileStream)
{
fclose(m_pFileStream);
m_pFileStream =
NULL
;
}
}
//文件全路径得到文件名
const
char
*CLogger::path_file(
const
char
*path,
char
splitter)
{
return
strrchr
(path, splitter) ?
strrchr
(path, splitter) +
1
: path;
}
//写严重错误信息
void
CLogger::TraceFatal(
const
char
*lpcszFormat, ...)
{
//判断当前的写日志级别
if
(EnumLogLevel::LogLevel_Fatal > m_nLogLevel)
return
;
string
strResult;
if
(
NULL
!= lpcszFormat)
{
va_list marker =
NULL
;
va_start(marker, lpcszFormat);
//初始化变量参数
size_t
nLength = _vscprintf(lpcszFormat, marker) +
1
;
//获取格式化字符串长度
std
::
vector
<
char
> vBuffer(nLength,
'\0'
);
//创建用于存储格式化字符串的字符数组
int
nWritten = _vsnprintf_s(&vBuffer[
0
], vBuffer.size(), nLength, lpcszFormat, marker);
if
(nWritten >
0
)
{
strResult = &vBuffer[
0
];
}
va_end(marker);
//重置变量参数
}
if
(strResult.empty())
{
return
;
}
string
strLog = strFatalPrefix;
strLog.append(GetTime()).append(strResult);
//写日志文件
Trace(strLog);
}
//写错误信息
void
CLogger::TraceError(
const
char
*lpcszFormat, ...)
{
//判断当前的写日志级别
if
(EnumLogLevel::LogLevel_Error > m_nLogLevel)
return
;
string
strResult;
if
(
NULL
!= lpcszFormat)
{
va_list marker =
NULL
;
va_start(marker, lpcszFormat);
//初始化变量参数
size_t
nLength = _vscprintf(lpcszFormat, marker) +
1
;
//获取格式化字符串长度
std
::
vector
<
char
> vBuffer(nLength,
'\0'
);
//创建用于存储格式化字符串的字符数组
int
nWritten = _vsnprintf_s(&vBuffer[
0
], vBuffer.size(), nLength, lpcszFormat, marker);
if
(nWritten >
0
)
{
strResult = &vBuffer[
0
];
}
va_end(marker);
//重置变量参数
}
if
(strResult.empty())
{
return
;
}
string
strLog = strErrorPrefix;
strLog.append(GetTime()).append(strResult);
//写日志文件
Trace(strLog);
}
//写警告信息
void
CLogger::TraceWarning(
const
char
*lpcszFormat, ...)
{
//判断当前的写日志级别
if
(EnumLogLevel::LogLevel_Warning > m_nLogLevel)
return
;
string
strResult;
if
(
NULL
!= lpcszFormat)
{
va_list marker =
NULL
;
va_start(marker, lpcszFormat);
//初始化变量参数
size_t
nLength = _vscprintf(lpcszFormat, marker) +
1
;
//获取格式化字符串长度
std
::
vector
<
char
> vBuffer(nLength,
'\0'
);
//创建用于存储格式化字符串的字符数组
int
nWritten = _vsnprintf_s(&vBuffer[
0
], vBuffer.size(), nLength, lpcszFormat, marker);
if
(nWritten >
0
)
{
strResult = &vBuffer[
0
];
}
va_end(marker);
//重置变量参数
}
if
(strResult.empty())
{
return
;
}
string
strLog = strWarningPrefix;
strLog.append(GetTime()).append(strResult);
//写日志文件
Trace(strLog);
}
//写一般信息
void
CLogger::TraceInfo(
const
char
*lpcszFormat, ...)
{
//判断当前的写日志级别
if
(EnumLogLevel::LogLevel_Info > m_nLogLevel)
return
;
string
strResult;
if
(
NULL
!= lpcszFormat)
{
va_list marker =
NULL
;
va_start(marker, lpcszFormat);
//初始化变量参数
size_t
nLength = _vscprintf(lpcszFormat, marker) +
1
;
//获取格式化字符串长度
std
::
vector
<
char
> vBuffer(nLength,
'\0'
);
//创建用于存储格式化字符串的字符数组
int
nWritten = _vsnprintf_s(&vBuffer[
0
], vBuffer.size(), nLength, lpcszFormat, marker);
if
(nWritten >
0
)
{
strResult = &vBuffer[
0
];
}
va_end(marker);
//重置变量参数
}
if
(strResult.empty())
{
return
;
}
string
strLog = strInfoPrefix;
strLog.append(GetTime()).append(strResult);
//写日志文件
Trace(strLog);
}
//获取系统当前时间
string
CLogger::GetTime()
{
time_t
curTime;
time(&curTime);
tm tm1;
localtime_s(&tm1, &curTime);
//2016-01-01 21:30:00
string
strTime = FormatString(
"%04d-%02d-%02d %02d:%02d:%02d "
, tm1.tm_year +
1900
, tm1.tm_mon +
1
, tm1.tm_mday, tm1.tm_hour, tm1.tm_min, tm1.tm_sec);
return
strTime;
}
//改变写日志级别
void
CLogger::ChangeLogLevel(EnumLogLevel nLevel)
{
m_nLogLevel = nLevel;
}
//写文件操作
void
CLogger::Trace(
const
string
&strLog)
{
try
{
//进入临界区
EnterCriticalSection(&m_cs);
//若文件流没有打开,则重新打开
if
(
NULL
== m_pFileStream)
{
fopen_s(&m_pFileStream, m_strLogFilePath.c_str(),
"a+"
);
if
(!m_pFileStream)
{
return
;
}
}
//写日志信息到文件流
fprintf
(m_pFileStream,
"%s\n"
, strLog.c_str());
fflush(m_pFileStream);
//离开临界区
LeaveCriticalSection(&m_cs);
}
//若发生异常,则先离开临界区,防止死锁
catch
(...)
{
LeaveCriticalSection(&m_cs);
}
}
string
CLogger::GetAppPathA()
{
char
szFilePath[MAX_PATH] = {
0
}, szDrive[MAX_PATH] = {
0
}, szDir[MAX_PATH] = {
0
}, szFileName[MAX_PATH] = {
0
}, szExt[MAX_PATH] = {
0
};
GetModuleFileNameA(
NULL
, szFilePath,
sizeof
(szFilePath));
_splitpath_s(szFilePath, szDrive, szDir, szFileName, szExt);
string
str
(szDrive)
;
str.append(szDir);
return
str;
}
string
CLogger::FormatString(
const
char
*lpcszFormat, ...)
{
string
strResult;
if
(
NULL
!= lpcszFormat)
{
va_list marker =
NULL
;
va_start(marker, lpcszFormat);
//初始化变量参数
size_t
nLength = _vscprintf(lpcszFormat, marker) +
1
;
//获取格式化字符串长度
std
::
vector
<
char
> vBuffer(nLength,
'\0'
);
//创建用于存储格式化字符串的字符数组
int
nWritten = _vsnprintf_s(&vBuffer[
0
], vBuffer.size(), nLength, lpcszFormat, marker);
if
(nWritten >
0
)
{
strResult = &vBuffer[
0
];
}
va_end(marker);
//重置变量参数
}
return
strResult;
}
}
有图有真相:
版权声明:本文为博主原创文章,转载请注明原帖地址。 https://blog.csdn.net/sunflover454/article/details/49758801
你可能感兴趣的文章
GitHub + Hexo 搭建个人博客
查看>>
Linux Ubuntu 修改网卡名字
查看>>
OpenStack Ocata Horizon 开发(一)—— 快速开始
查看>>
自定义Horizon
查看>>
Django 源码阅读:服务启动(wsgi)
查看>>
Django 源码阅读:url解析
查看>>
第三轮面试题
查看>>
Docker面试题(一)
查看>>
第四轮面试题
查看>>
第一轮面试题
查看>>
2020-11-18
查看>>
Docker面试题(二)
查看>>
一、redis面试题及答案
查看>>
消息队列2
查看>>
消息列队3
查看>>
spring cloud 面试题总结
查看>>
第二轮面试题
查看>>
2021-04-27
查看>>
SSM 写出乐淘商城
查看>>
高精尖面试题汇总
查看>>