这里面有个细节大家注意一下,asctime这个系统函数很讨厌,它格式化的字符串,后自动带着一个回车,这会打乱我的输出顺序,所以我用了 szBuf[nPrintLength-1]=''; 这句话来回退,消灭这个多余的回车。

  当然,有了这个时间戳宏,我们也可以很轻松写出SafePrintf的时间戳版本:

  Code:

inline int SafePrintfWithTimestamp(char* szBuf,int nBufSize,char* szFormat, ...)  
{  
    if(!szBuf) return 0;  
    if(!nBufSize) return 0;  
    if(!szFormat) return 0;  
    int nRet=0;  
    TONY_FORMAT_WITH_TIMESTAMP(nRet,szBuf,nBufSize,szFormat);  
    return nRet;  
}

  还是要给个测试嘛:

  Code:

inline void Test_TONY_FORMAT(void)  
{  
    char szBuf[256];  
    int nLength=0;  
    nLength=SafePrintf(szBuf,256,"Test: %d",100);  
    printf("[%d] %s ",nLength,szBuf);  
    nLength=SafePrintfWithTimestamp(szBuf,256,"Test: %d",100);  
    printf("[%d] %s ",nLength,szBuf);  
}

  结果:

  [9] Test: 100

  [36] [Wed May 12 10:10:32 2010] Test: 100

  不过,为了仔细甄别,我还是单独写了两个变参处理函数来验证这个变参传递情况,第一个模拟printf,第二个模拟fprintf,大家可以看看代码。

  这是printf版本:

  Code:

#define TONY_LINE_MAX 1024      //大一行输出的字符数  
//输出到控制台  
inline int TonyPrintf(bool bWithTimestamp,      //是否带时间戳标志  
                      char* szFormat, ...)      //格式化字符串  
{  
    if(!szFormat) return 0;  
    char szBuf[TONY_LINE_MAX];  
    int nLength=0;  
    if(!bWithTimestamp)           
    {   //注意,由于内部是函数型宏,if...else这个大括号必不可少  
        TONY_FORMAT(nLength,szBuf,TONY_LINE_MAX,szFormat);  
    }   //注意,由于内部是函数型宏,if...else这个大括号必不可少  
    else 
    {   //注意,由于内部是函数型宏,if...else这个大括号必不可少  
        TONY_FORMAT_WITH_TIMESTAMP(nLength,szBuf,TONY_LINE_MAX,szFormat);  
    }   //注意,由于内部是函数型宏,if...else这个大括号必不可少  
    return printf(szBuf);  
}  
inline void TestTonyPrintf(void)  
{  
    int i=0;  
    double dTest=123.456;  
    unsigned int unTest=0xAABBCC;  
    for(i='A';i<='E';i++)  
    {  
        TonyPrintf(0,"[%d]: %0.2f, %c, 0x%08X ",i,dTest,i,unTest);  
    }  
    for(i='A';i<='E';i++)  
    {  
        TonyPrintf(1,"[%d]: %0.2f, %c, 0x%08X ",i,dTest,i,unTest);  
    }  
}