运行结果:

  [65]: 123.46, A, 0x00AABBCC
  [66]: 123.46, B, 0x00AABBCC
  [67]: 123.46, C, 0x00AABBCC
  [68]: 123.46, D, 0x00AABBCC
  [69]: 123.46, E, 0x00AABBCC
  [Wed May 12 09:17:43 2010] [65]: 123.46, A, 0x00AABBCC
  [Wed May 12 09:17:43 2010] [66]: 123.46, B, 0x00AABBCC
  [Wed May 12 09:17:43 2010] [67]: 123.46, C, 0x00AABBCC
  [Wed May 12 09:17:43 2010] [68]: 123.46, D, 0x00AABBCC
  [Wed May 12 09:17:43 2010] [69]: 123.46, E, 0x00AABBCC

  fprintf版本比较麻烦一点,需要先创建一根文件指针。

  Code:

//输出到文件  
inline int TonyFPrintf(FILE* fp,                //文件指针  
                       bool bWithTimestamp,     //是否带时间戳标志  
                      char* szFormat, ...)      //格式化字符串  
{  
    if(!fp) return 0;  
    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 fprintf(fp,szBuf);  
}  
inline void TestTonyFPrintf(void)  
{  
    FILE* fp=null;  
    int i=0;  
    double dTest=123.456;  
    unsigned int unTest=0xAABBCC;  
    fp=fopen("test.txt","at");  
    if(fp)  
    {  
        for(i='A';i<='E';i++)  
        {  
            TonyFPrintf(fp,0,"[%d]: %0.2f, %c, 0x%08X ",i,dTest,i,unTest);  
        }  
        for(i='A';i<='E';i++)  
        {  
            TonyFPrintf(fp,1,"[%d]: %0.2f, %c, 0x%08X ",i,dTest,i,unTest);  
        }  
        fclose(fp);  
    }  
}

  这个函数运行完后,屏幕上没有,不过,磁盘上会出现一个文件,叫做test.txt,里面的内容和前面的一样。

  经过这些测试,我认为这次改版基本上成功了,使用这几个变参处理宏,我可以大幅度缩减很多变参函数的书写长度,程序显得很清爽,且功能比较完备。

  我的计划是,这些代码目前先自己用,等用个一年半载,稳定性差不多了,在《0bug-C/C++商用工程之道》的第二版中,我会应用到新的工程库中去,供各位读者使用哈。

  上述代码在VS2008下测试通过,不过,我的理解是跨平台的,由于全部是C的函数,处理的都是函数内部私有变量,因此,也是线程安全的。

  大家看看,有问题再问哈。