win32 编程之调试输出
来源:互联网 发布:骑士vs火箭数据 编辑:程序博客网 时间:2024/05/16 19:51
在windows下编程时,不能再使用printf了,需要使用sprintf、wsprintf,或者采用MessageBox弹出对话框来输出相应的值。
#include <stdarg.h>int CDECL MessageBoxPrintf (TCHAR * szCaption, TCHAR * szFormat, ...){ TCHAR szBuffer [1024] ; va_list pArgList ; // The va_start macro (defined in STDARG.H) is usually equivalent to: // pArgList = (char *) &szFormat + sizeof (szFormat) ; va_start (pArgList, szFormat) ; _vsntprintf (szBuffer, sizeof (szBuffer) / sizeof (TCHAR), szFormat, pArgList) ; va_end (pArgList) ;// The va_end macro just zeroes out pArgList for no good reason return MessageBox (NULL, szBuffer, szCaption, 0) ;}
上面这段代码来自《windows程序设计》,对MessageBox稍微进行了改进。函数前的CDECL很少见,其实它和_cdecl是一样的,只是名字不同。MessageBoxPrintf使用方法如下:
MessageBoxPrintf (TEXT ("ScrnSize"),TEXT ("The screen is %i pixels wide by %i pixels high."),100, 200) ;
windows有很多输出函数,常用的是sprintf、wsprintf,这些函数不能像C语言中的printf函数那样,可以直接输出,而是把数据输出到一个缓冲区,再通过MessageBox将缓冲区的内容显示出来。上面的_vsntprintf的原理也是一样,只是它支持的缓冲区更大一些,并且支援ascii与unicode字符。
比较难理解其实是那个va_list、va_start、va_end,还有它们的兄弟va_arg函数,这些函数来自于<stdarg.h>,在vc++6.0中,实现代码如下:
typedef char * va_list;#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )#define va_end(ap) ( ap = (va_list)0 )
上面这几句代码并不好理解,除了最后那个va_end回收内存好理解以外,其它代码都值得细究一下。
1,关于(sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1),主要解决的就是“内存对齐”,因为在32位操作系统上int是占32位(4个字节),但是原来的系统不一定是4个字节,有可能是2个字节,这段代码就是来解决如果某编译平台上int占4个以下的字节时,把它提升为占4个字节。如sizeof(n)为2,则(2+3)&~3=4.
2,va_start的作用,MessageBoxPrintf的注释大概也清楚了。(va_list)&v指的是"The screen is %i pixels wide by %i pixels high."的首字符地址,而+ _INTSIZEOF(v)就相当于是将字符指针加到“.”(这个字符串的最后一个字符)的下一个字符,即执行va_start函数后,ap实际上已经指向了参数100的地址。
3,需要注意的是va_start的第二个参数,一定要是“...”之前的那个参数(此处即为szFormat)。
但是上面的程序没有用到va_args这个函数,下面再举一个例子,下面的代码完成的一个精简版的printf函数,它可以指定任意个输出参数:
void minprintf(char *fmt,...){va_list ap;char *p,*sval;int ival;double dval;va_start(ap,fmt);for(p = fmt;*p;p++){if(*p != '%'){putchar(*p);continue;}switch(* ++p){case 'd':ival = va_arg(ap,int);printf("%d",ival);break;case 'f':dval = va_arg(ap,int);printf("%d",dval);break;case 's':for(sval = va_arg(ap,char *); *sval;sval++){putchar(*sval);}break;default:putchar(*p);break;}}va_end(ap);}这个代码来自《C程序设计语言》,很经典,我们可以这样调用:
minprintf("===%d==%d===%d\n",15,30,45);
3,va_args这个函数比较难理解,(ap += _INTSIZEOF(t)) - _INTSIZEOF(t)这个代码有两个意思。
(1),ap指向下一个参数的地址,作用代码(ap += _INTSIZEOF(t)) 。因为上面的代码调用va_start使ap指向15的地址,所以调用va_args后,ap就指向第二变参,即30的地址;
(2),返回ap指向的前一个地址(即参数15的地址),因为此时ap已经指向了下一个参数的地址,所以要 - _INTSIZEOF(t)。而(t *)作用是将返回的地址轮换成一个指针(即15的地址),再用*取得这个指针指向的值(即15)。
- win32 编程之调试输出
- Win32编程调试信息的输出(Console)
- win32自建调试输出窗口
- QT + WIN32 调试信息输出
- win32程序启用控制台-- 调试输出
- win32/vc 程序调试信息命令行输出
- win32程序启用控制台-- 调试输出
- win32程序启用控制台-- 调试输出
- WIN32编程之DialogBox
- Win32编程之WinMain
- win32编程之俄罗斯方块
- win32编程之进程
- Win32系统编程之四书五经
- Win32之Windows编程基础
- WinSDK编程另类调试输出
- win32使用OutputDebugString输出调试信息的方法
- Win32应用程序使用Console窗口输出调试信息
- MFC,Win32程序向控制台(Console)窗口输出调试信息
- 百度贴吧“神来一句”功能分析
- R语言与网站分析 第7章分类指…
- R语言与网站分析 第8章样本分…
- Maven经验分享(五)Maven拷贝资源
- R导论中文版
- win32 编程之调试输出
- R语言与网站分析 第9章:样本…
- js-字符串中去除含有的某些字符串
- 执行maven时报内存溢出OutOfMemory
- Java Date工具类
- git reset revert 回退回滚取消提交返回上一版本
- MySQL的SQL查询优化
- Maven经验分享(六)Jboss热部署
- Python第二弹:数据处理