18、通过可变参数实现打印日志

简介: 在c和c++中,可变参数使用的最多函数有:scanf,printf,以及fprintf,fscanf,sprintf等,MFC也提供CString::Format实现可变参数。 本示例通过va_list来实现自己的可变参数函数,实现程序写日志功能。

cc++中,可变参数使用的最多函数有:scanfprintf,以及fprintffscanfsprintf等,MFC也提供CString::Format实现可变参数。

本示例通过va_list来实现自己的可变参数函数,实现程序写日志功能。

通过可变参数实现日志打印
// ForATest.cpp : 定义控制台应用程序的入口点。
#include " stdafx.h "
#include
" Windows.h "
#include
" iostream "
using namespace std;
#include
" string "
#include
< stdio.h >
#include
< stdarg.h >
#define PL_ERROR -2
#define SERVICE_ERROR(strMod, ulErrCode, cFormat, ...) \
logRecord(__FUNCTION__, __LINE__, strMod, PL_ERROR, ulErrCode, cFormat, __VA_ARGS__);
static string TestIT_MODULE = " TestItMe " ;
void logRecord( string strFunc,
int iLine,
string strMod,
int iLevel,
int iErrCode,
char * cFormat,
...)
{
string strLog;
strLog.clear();
char acBuffer1[ 255 ], acBuffer2[ 255 ];
sprintf_s(acBuffer1,
254 , " [%s] [%d] [%s] [%d] [%d] " , strFunc.data(), iLine, strMod.data(), iLevel, iErrCode);
va_list args;
va_start (args, cFormat);
vsprintf(acBuffer2,cFormat, args);
FILE
* pFile = fopen( " C:\\log.txt " , " a+ " );
if (NULL == pFile)
return ;
fprintf(pFile, acBuffer1);
fprintf(pFile, acBuffer2);
fprintf(pFile,
" \n " );
fclose(pFile);
va_end(args);
}
int _tmain( int argc, _TCHAR * argv[])
{
string strFileName = " C:\\Intel\\Logs " ;
SERVICE_ERROR(TestIT_MODULE,
- 1 , " GetFile %s Attributes fail error code %d " , strFileName.data(), GetLastError());
}
sprintf_s的一个示例
#include < stdio.h >
#include
" string "
#include
" iostream "
using namespace std;
int main( void )
{
char buffer[ 200 ], s[] = " computer " , c = ' l ' ;
int i = 35 , j;
float fp = 1.7320534f ;
string name = " hello " ;
// Format and print various data:
j = sprintf_s( buffer, 200 , " String: %s\n " , s );
j
+= sprintf_s( buffer + j, 200 - j, " Character: %c\n " , c );
j
+= sprintf_s( buffer + j, 200 - j, " Integer: %d\n " , i );
j
+= sprintf_s( buffer + j, 200 - j, " Real: %f\n " , fp );
j
+= sprintf_s( buffer + j, 200 - j, " Name: %s\n " , name.data() );
printf_s(
" Output:\n%s\ncharacter count = %d\n " , buffer, j );
}
img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif C++ version 
// AssistTest.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include
"cstdio"
#include
"iostream"
#include
"string"
#include
"fstream"
#include
"cstdarg"
#include
"windows.h"

using namespace std;

const int OP_SUCCESS = 0;
const int OP_FAILED = -1;
static string TestIT_MODULE = "TestItMe";

#define SERVICE_ERROR(strMod, ulErrCode, cFormat, ...) \
logRecord(__FUNCTION__, __LINE__, strMod, ulErrCode, cFormat, __VA_ARGS__);

//print log module
void logRecord(string strFunc,
int iLine,
string strMod,
int iErrCode,
char* cFormat,
...)
{
string strLog;
strLog.clear();
char acBuffer1[255], acBuffer2[255];
sprintf_s(acBuffer1,
254, "[%s] [%d] [%s] [%d] ", strFunc.data(), iLine, strMod.data(), iErrCode);
va_list args;
va_start (args, cFormat);
vsprintf(acBuffer2,cFormat, args);

ofstream ofLogFile;
ofLogFile.open(
"F:\\log.txt", ios::out | ios::app);
if (!ofLogFile)
{
return;
}

string strBuffer1, strBuffer2;
strBuffer1
= acBuffer1;
strBuffer2
= acBuffer2;

ofLogFile.write(strBuffer1.data(), strBuffer1.size());
ofLogFile.write(strBuffer2.data(), strBuffer2.size());
ofLogFile.put(
'\n');
ofLogFile.close();

va_end(args);
}

int main(int argc, char* argv[])
{
string strFileName = "C:\\Intel\\Logs";
SERVICE_ERROR(TestIT_MODULE,
-1, "GetFile %s Attributes fail error code %d", strFileName.data(), GetLastError());
}
img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif C++ version 2
// AssistTest.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include
"cstdio"
#include
"iostream"
#include
"string"
#include
"fstream"
#include
"cstdarg"
#include
"windows.h"

using namespace std;

const int OP_SUCCESS = 0;
const int OP_FAILED = -1;
static string TestIT_MODULE = "TestItMe";

class mt
{
public:
void LogRecord(string strFunc, unsigned int uiLine, string strMod, int iulErrCode, char* cFormat, ...);
//print log module
};

void mt::LogRecord(string strFunc,
unsigned
int uiLine,
string strMod,
int iErrCode,
char* cFormat,
...)
{
string strLog;
strLog.clear();
char acBuffer1[255], acBuffer2[255];
sprintf_s(acBuffer1,
254, "[%s] [%d] [%s] [%d] ", strFunc.data(), uiLine, strMod.data(), iErrCode);
va_list args;
va_start (args, cFormat);
vsprintf(acBuffer2,cFormat, args);

ofstream ofLogFile;
ofLogFile.open(
"F:\\log.txt", ios::out | ios::app);
if (!ofLogFile)
{
return;
}

string strBuffer1, strBuffer2;
strBuffer1
= acBuffer1;
strBuffer2
= acBuffer2;

ofLogFile.write(strBuffer1.data(), strBuffer1.size());
ofLogFile.write(strBuffer2.data(), strBuffer2.size());
ofLogFile.put(
'\n');
ofLogFile.close();

va_end(args);
}

int main(int argc, char* argv[])
{
string strFileName = "C:\\Intel\\Logs";
mt m1;
m1.LogRecord(__FUNCTION__, __LINE__ ,TestIT_MODULE,
-1, "GetFile %s Attributes fail error code %d", strFileName.data(), GetLastError());
}

参考

[1] http://www.cplusplus.com/reference/clibrary/cstdio/vsprintf/

[2] http://www.cnblogs.com/stuarts/archive/2010/08/03/1791598.html

[3] http://www.cnblogs.com/mydomain/archive/2010/07/27/1785667.html

讲述了了va_start等可变参数的基本概念及定义

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
7月前
|
Java C++
C++可变参数
C++可变参数
40 0
|
8月前
|
C++
C和C++中的可变参数(上)
C和C++中的可变参数(上)
64 0
|
6月前
|
测试技术 Python
软件测试|Python函数参数之必传参数、默认参数、可变参数、关键字参数的详细使用
软件测试|Python函数参数之必传参数、默认参数、可变参数、关键字参数的详细使用
55 0
|
9月前
|
存储 C++ Python
关于函数参数传递,80%人都错了
实际的输出我想大家都尝试过了吧,应该是选项二:
|
10月前
|
NoSQL 编译器 Shell
C++可变参数使用总结
C++可变参数使用总结
|
11月前
|
Python
python函数不能传可变参数
python函数不能传可变参数
|
12月前
可变参数方法设计
可变参数方法设计
定义带参数的C宏,方便输出调试信息
定义带参数的C宏,方便输出调试信息
53 0
|
Java
一文学会java方法重载,可变参数
1.概述 重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。 每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。 最常用的地方就是构造器的重载。
127 0
|
Java
java方法详解(有无返回值、重载)
方法一般创建在mian方法外,方法比较害羞,不调用就不执行
117 0