c自定义日志方法va_list
/* * Portions created by SGI are Copyright (C) 2000 Silicon Graphics, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Silicon Graphics, Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> #include "st.h" /* * Simple error reporting functions. * Suggested in W. Richard Stevens' "Advanced Programming in UNIX * Environment". */ #define MAXLINE 4096 /* max line length */ static void err_doit(int, int, const char *, va_list); /* * Nonfatal error related to a system call. * Print a message and return. */ void err_sys_report(int fd, const char *fmt, ...) { va_list ap; va_start(ap, fmt); err_doit(fd, 1, fmt, ap); va_end(ap); } /* * Fatal error related to a system call. * Print a message and terminate. */ void err_sys_quit(int fd, const char *fmt, ...) { va_list ap; va_start(ap, fmt); err_doit(fd, 1, fmt, ap); va_end(ap); exit(1); } /* * Fatal error related to a system call. * Print a message, dump core, and terminate. */ void err_sys_dump(int fd, const char *fmt, ...) { va_list ap; va_start(ap, fmt); err_doit(fd, 1, fmt, ap); va_end(ap); abort(); /* dump core and terminate */ exit(1); /* shouldn't get here */ } /* * Nonfatal error unrelated to a system call. * Print a message and return. */ void err_report(int fd, const char *fmt, ...) { va_list ap; va_start(ap, fmt); err_doit(fd, 0, fmt, ap); va_end(ap); } /* * Fatal error unrelated to a system call. * Print a message and terminate. */ void err_quit(int fd, const char *fmt, ...) { va_list ap; va_start(ap, fmt); err_doit(fd, 0, fmt, ap); va_end(ap); exit(1); } /* * Return a pointer to a string containing current time. */ char *err_tstamp(void) { static char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; static char str[32]; static time_t lastt = 0; struct tm *tmp; time_t currt = st_time(); if (currt == lastt) return str; tmp = localtime(&currt); sprintf(str, "[%02d/%s/%d:%02d:%02d:%02d] ", tmp->tm_mday, months[tmp->tm_mon], 1900 + tmp->tm_year, tmp->tm_hour, tmp->tm_min, tmp->tm_sec); lastt = currt; return str; } /* * Print a message and return to caller. * Caller specifies "errnoflag". */ static void err_doit(int fd, int errnoflag, const char *fmt, va_list ap) { int errno_save; char buf[MAXLINE]; errno_save = errno; /* value caller might want printed */ strcpy(buf, err_tstamp()); /* prepend a message with time stamp */ vsprintf(buf + strlen(buf), fmt, ap); if (errnoflag) sprintf(buf + strlen(buf), ": %s\n", strerror(errno_save)); else strcat(buf, "\n"); write(fd, buf, strlen(buf)); errno = errno_save; }
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <string>
void simple_va_fun(char * fmt, ...) {
#define TEMP_BUF_LEN 200
char buf[TEMP_BUF_LEN];
unsigned int index,i,len,prelen;
int itemp;
char *stemp;
va_list ap;
memset(buf,0, TEMP_BUF_LEN);
len = strlen(fmt);
va_start(ap,fmt);
for (index = 0, i=0;i<len;i++) {
// 如果不是控制字符
if (fmt[i] != '%') {
buf[index++] = fmt[i]; // 直接输出
continue;
}
i++;
if ('\0'==fmt[i]) {
assert(0); // 这是一个错误
break;
}
switch(fmt[i]) {
case '%': // 连续两个'%'输出一个'%'
buf[index++] = '%';
break;
case 'd': // 按照int输出
itemp = va_arg(ap, int);
prelen = strlen(buf);
sprintf(buf + index, "%d", itemp);
index += strlen(buf)- prelen;
break;
case 's':
stemp = va_arg(ap, char*);
strcpy(buf + index, stemp);
index += strlen(stemp);
break;
}
}
buf[index] = '\0';
va_end(ap);
printf("Result:%s\n",buf);
}
int main() {
simple_va_fun("index=%d,context=%s\n",123,"Hello");
printf("Over");
getchar();
return 0;
}
自定义调试信息的输出
qDebug( "[模块名称] 调试信息 File:%s, Line:%d", __FILE__, __LINE__ );
这样的修改比较烦人, 而且一不小心会遗漏某个没改的...
2) __FILE__ 宏在预编译时会替换成当前的源文件名
3) __LINE__宏在预编译时会替换成当前的行号
4) __FUNCTION__宏在预编译时会替换成当前的函数名称
有时,我们想把调试信息输出到屏幕上,而有时则又想把它输出到一个文件中,可参考下面的例子:
#include <string.h>
#define _DEBUG
//开启下面的宏就把调试信息输出到文件,注释即输出到终端
#define DEBUG_TO_FILE
#ifdef DEBUG_TO_FILE
//调试信息输出到以下文件
#define DEBUG_FILE "/tmp/debugmsg"
//调试信息的缓冲长度
#define DEBUG_BUFFER_MAX 4096
//将调试信息输出到文件中
#define printDebugMsg(moduleName, format, ...) {\
char buffer[DEBUG_BUFFER_MAX+1]={0};\
snprintf( buffer, DEBUG_BUFFER_MAX \
, "[%s] "format" File:%s, Line:%d\n", moduleName, ##__VA_ARGS__, __FILE__, __LINE__ );\
FILE* fd = fopen(DEBUG_FILE, "a");\
if ( fd != NULL ) {\
fwrite( buffer, strlen(buffer), 1, fd );\
fflush( fd );\
fclose( fd );\
}\
}
#else
//将调试信息输出到终端
#define printDebugMsg(moduleName, format, ...) \
printf( "[%s] "format" File:%s, Line:%d\n", moduleName, ##__VA_ARGS__, __FILE__, __LINE__ );
#endif //end for #ifdef DEBUG_TO_FILE
#else
//发行版本,什么也不做
#define printDebugMsg(moduleName, format, ...)
#endif //end for #ifdef _DEBUG
{
int data = 999;
printDebugMsg( "TestProgram", "data = %d", data );
return 0;
}
{
char buffer[DEBUG_BUFFER_MAX_LENGTH + 1]={0};
va_start (arg, format);
vsnprintf(buffer, DEBUG_BUFFER_MAX_LENGTH, format, arg);
va_end (arg);
}