一个很好用的调试辅助类,使用需要一定C++基础
很多时候我们需要把程序运行过程中的一些临时变量显示出来,一般我们可以通过wcout或cout类将调式信息输出到控制台。但有时我们需要将调试信息输出到别的地方,比如VS.net的“输出”窗口就比较麻烦了,可能需要频繁的在字符串和数字间相互转换,这对于C++程序员来说可真是一场恶梦。下面提出一种方案,可以很好的解决这个问题。即利用替换wcout或cout的内部字符串缓存的方法,使写入到wcout或cout的字符串转写到其它的设备中。
"["C-^5R+C)Q程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码,黑客,安全,技术社区,技术论坛;x9Q8Z)t"H3T,z$a
第一步:在你整个工程的头文件,比如stdafx.h里的下面加入以下代码。这是用于wcout或cout的字符串缓存类。 'H%r0X*q4E'C$]
tech.techweb.com.cn5i3A;a6H$o I$j!i
&m+R:F:@'W,{#R;?
C/C++ codetech.techweb.com.cn({$^/^&T!U,[1~7H2B:M
#include <iostream>
t7A-^3e#Q"Z4w+M6Ztech.techweb.com.cn#include <algorithm>
2{)Q*y/H8Q0w;T%H#include <sstream>
-Y0U)Y2L.u*R8X$f!P9O#include <tchar.h>TechWeb-技术社区#}+v6|9N1h5}-D*o0z-B1h
using namespace std;
7@&[.}&x0c"g9B,Rtemplate<class _Elem, class _Traits = char_traits<_Elem> >'z)W5C#[)D&Y(y.S!n
class CDebugStreamBuf : public basic_stringbuf<_Elem, _Traits >程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码,黑客,安全,技术社区,技术论坛4N4H'y0J9t,h5L!D%E(u
{ // 回调函数接受一个准备输出到设备的字符串参数。
.g;d7U7o&f&t5X/cpublic: // 如果回调函数返回false,缓存对象的_Mystate将被设为BAD,并不再继续写入。
&W4K w-E/s2i9Htech.techweb.com.cn typedef bool (__stdcall *_Myof)( const _Elem* );-[6i/x U)J#`$L2W*P"i
explicit inline CDebugStreamBuf( _Myof _Outfunc )
k:^*S8x S;N&h"Q/T ~6?.V : _Myoutfunc( _Outfunc ){} // 初始化回调函数TechWeb-技术社区/M2A7E8Z7]&E3o5s5F
virtual ~CDebugStreamBuf( void ){} // 虚析构函数
5x&T*c*b5i4E9stech.techweb.com.cnprotected: // 每次同步都会刷新缓存中的所有内容程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码,黑客,安全,技术社区,技术论坛3q/k-B;C!{4~#K
virtual int sync( void ) // 重载sync函数,将在需要输入到设备(同步)时被调用8P&N0w5h5Q!I6j+h
{ // 如果无回调函数或缓冲未初始化,返回错误。_Mystate将被设为BAD/P-X;P!j+v3T*[
if ( _Myoutfunc == 0 || pptr() == 0 ) return -1;
/];b(v$e;c2Q&t0Ytech.techweb.com.cn else if ( _Mysb::pbase() >= _Mysb::epptr() ) return 0;程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码,黑客,安全,技术社区,技术论坛+^3W5H-]1c)]1o0|
else // 确保缓存可以写入tech.techweb.com.cn-y,|/}7E"\
{ // 将当前写指针的后一位改写为0,如果缓存长度不足将调用overflow执行添加TechWeb-技术社区.R7Z0h4A5L(|!~!X
sputc( _Traits::to_char_type( 0 ) );
$o$U,A Y,o9g&P9Stech.techweb.com.cn setg( pbase(), pbase(), pptr() ); // 将读指针设为缓存起点
-k+G9x7@&E*W seekpos( 0, ios_base::out ); // 将写指针置0以备下次从起点写入9[&m:t!Y+E/U'G
for ( ; gptr() < egptr(); ) // 遍例+_)t+Q o5W;K"g
{ //忽略包括当前指针在内后面的所有0值TechWeb-技术社区;_)x$k-K)r,V9J
for ( ; !sbumpc(); );
4`%J0|$y)^#i8w6s;h if ( !_Myoutfunc( gptr() - 1 ) ) return -1; // 输出字符串
!N*R(J3N!N9h.J7i:a'g gbump( (int)( find( gptr(), egptr(), // 找到下一个0值!o.k+F/Q2Q'Z
_Traits::to_char_type( 0 ) ) - gptr() + 1 ) );tech.techweb.com.cn$d+?$a5U(e!b3C7y:c4y2R
}TechWeb-技术社区4z)X7}0h'e
}
-x$_5T/j#n8F!E8?2Jtech.techweb.com.cn return 0;8u9U9B3e6p
}2k"K4D1Y1d0{(x2a&G,f
protected:tech.techweb.com.cn+}5m8y;Y;E2o4^,P
_Myof _Myoutfunc; // 回调函数成员,必须在构造时初始化-F;n-g4l3e&x5Y
};
(X$U6s"E7X&m/U.^
.s'^"\7L!|0D7f*w-R!V'v'V)X!K"P"~
%j&E1o,x!J3^0Z3{(V e)P!R6q#a"P&\
第二步:在包含(#include)第一步所选头文件的任意一个代码文件(*.cpp)顶部,包含头文件说明的下面加入如下代码。在这里我们对字符串缓存类的对象进行了初始化,并自己定义了一个回调函数。该回调函数将接受来自缓存类的调式自符串,然后将它输出到VS.net的“输出”窗口。当然,你也可以自己定义这样一个回调函数使字符串写入磁盘映像或SOCKET之类更复杂的设备。 tech.techweb.com.cn"B!_*t#|&r&O1u
'`4X&['X7^(AC/C++ code
/B9k6q(u,p程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码,黑客,安全,技术社区,技术论坛bool CALLBACK MyOutputDebugString( LPCTSTR lpText )0C8F1?%?7E(A+{
{%y7F)d7Y1c;m
OutputDebugString( lpText );
5|9Q%}#W4Y"{.\(U:yTechWeb-技术社区 return true;
2q/R8z!v `&{*S}
1R+`#O*P8~5y3l&c!|,TCDebugStreamBuf<TCHAR> g_DbgBuf( MyOutputDebugString );
4}/K*n'K'K r0t&I
(e7v2D*?)e$z程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码,黑客,安全,技术社区,技术论坛.['M j7|(Q3S1A0]+a
1F$g2l Z-[/x1T
TechWeb-技术社区#l1@$j3|!d0?'b6T;}0@
第三步:在任意一个类的初始化里加入如下代码(两行任选其一): 程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码,黑客,安全,技术社区,技术论坛"^;O$L1g,v3S"m e
;}#O!Q.R I8y3u,Y5l
C/C++ code
*i6d9a.k,O1y6a)P#?)Ptech.techweb.com.cn wcout.rdbuf( &g_DbgBuf ); // Unicode版本程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码,黑客,安全,技术社区,技术论坛*X;m"|$g4t(j)z
cout.rdbuf( &g_DbgBuf ); // 非Unicode版本
-I"r3V"n9D7MTechWeb-技术社区
3}.L;l)a#@)s!o-pTechWeb-技术社区
;p0Y1w9t9F"A:f(E6[6n%C8c*C,j%?:O
之后就可以方便的使用wcout或cout进行GDI程序的调式了,写入wcout或cout的字符串将全部显示在VS.net的“输出”窗口中。 TechWeb-技术社区7^,i2f2g:x,R1S*R
tech.techweb.com.cn s,m-m.d;i1Y,~
使用举例:
*T7N'L&x9q&O6J*n7i6t7_!@.U4|#q/u1C#j8|2{
C/C++ code
(k'Z(@-O!V7ITechWeb-技术社区 // TechWeb-技术社区6S+L:i2u%r4q1Q-g3c
CRect rc;
7I+l-l*k2| GetWindowRect( &rc );%H,[ W1I,K;y.[!j
wcout << _T("窗口的宽度是:") << rc.Width() <<!x'l4n$\1U/c4u(L
_T(",高度是:") << rc.Height() << endl;7q&T;l$~.W/p3W7N*\&x;U
:C8V1e,O$~0n;}4S"j*B+G
(K7A5J8n;w Q)[ dTechWeb-技术社区
9{#|$_,{8S0X9j:{
|