//=====================================================================
//TITLE:
// 格式化字符串至调试窗口
//AUTHOR:
// norains
//DATE:
// Wednesday 24- March-2010
//Environment:
// WINDOWS XP
//=====================================================================
如果是调试WinCE程序,需要将字符串格式化后输送到OutputWindow(调试窗口)则是一件非常简单的事情,只需要调用RETAILMSG,或是简单的printf函数即可;但对于WinXP则没有如此的幸运:虽然说可以调用OutputDebugString将字符串输送到Output Window,但却没有格式化的功能。
所以如果我们打算在WinXP环境下实现相应的功能,那么我们只能自己动手。其实这个函数我在另一篇文章《WinXP环境中模仿WinCE的ASSERT表现行为的解决方案》中有提到,但那也仅仅是简单罗列代码,并没有对其进行分析。故本文只是补缺,将该函数一一道来。
我将这个函数命名为DebugString,又因为其输入的参数是不可预知的,必须采用可变形参,故函数的声明如下:
void DebugStrng(TCHAR * pszFormat,...)
声明很简单,难题无外乎两个:
1. 如何确定形参的个数
2. 如何格式化字符串
当然,我们也不必为此大费周章,其实这两个难题都有相应的对策。
接下来,我们看看代码的实现。
首先是声明一个缓冲区,用来保存格式化的字符串:
TCHAR szText[1024];
可能大家初一看这大小,有点奇怪,为什么要定义为1024呢?其实这也由不得我,因为之后需要用到格式化字符串的函数所能接受的最大容量就是这个数。
接下来就是要考虑到可变形参的问题。还好,在C++中规定,我们可以通过va_start来开始枚举形参,但结束后,一定要通过va_end结束。为了避免期间出现意外,所以我们采用__try机制,无论发生什么事情,都一定要执行一次va_end:
__try { va_start(args, pszFormat); ... } __finally { va_end(args); } }
可变形参问题解决了,格式化字符串的问题也就不远了。因为我们有现成的wvsprintf函数,直接调用即可:
wvsprintf(szText, pszFormat, args);
字符串都格式好了,那么我们还有什么可以犹豫的?直接输出吧:
OutputDebugString(szText);
最后,虽然该函数在另一篇文章中已经有提过,但为了完整性,还是重新再列出其完整实现:
void DebugStrng(TCHAR * pszFormat,...) { //The maximum size of the buffer in the wvsprintf is 1024 bytes. TCHAR szText[1024]; //The argument pointer. va_list args; __try { //Start with the pstrFormat variable address va_start(args, pszFormat); //Format the string wvsprintf(szText, pszFormat, args); //Send the string to the output window OutputDebugString(szText); } __finally { //Stop enumerating the argument. va_end(args); } }