一个很好用的调试辅助类,使用需要一定C++基础
很多时候我们需要把程序运行过程中的一些临时变量显示出来,一般我们可以通过wcout或cout类将调式信息输出到控制台。但有时我们需要将调试信息输出到别的地方,比如VS.net的“输出”窗口就比较麻烦了,可能需要频繁的在字符串和数字间相互转换,这对于C++程序员来说可真是一场恶梦。下面提出一种方案,可以很好的解决这个问题。即利用替换wcout或cout的内部字符串缓存的方法,使写入到wcout或cout的字符串转写到其它的设备中。
*R3g'k,@*G7^/M:j3T-WTechWeb-技术社区/x-S*T#L0x5M.G&s&h2Z#i
第一步:在你整个工程的头文件,比如stdafx.h里的下面加入以下代码。这是用于wcout或cout的字符串缓存类。
-r8M4w7g)L2l!W;G程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码,黑客,安全,技术社区,技术论坛!D(|+A5n!^6U0T3Q
9E,?3p;B;w"{7PC/C++ code
6w8Z/X:r,X8\'T([#include <iostream>
4g:z7Q&?;\程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码,黑客,安全,技术社区,技术论坛#include <algorithm>
.I8~;w6I#d!\#include <sstream>
"Z#?(Y9w'@.U&`"k'T%X"qTechWeb-技术社区#include <tchar.h>1n;Q,U8l*U(R$W1U.T8Z
using namespace std; ?+^9j,h%v
template<class _Elem, class _Traits = char_traits<_Elem> >8t9s8Z R"x4N)u
class CDebugStreamBuf : public basic_stringbuf<_Elem, _Traits >
4y(g E,q!~2DTechWeb-技术社区{ // 回调函数接受一个准备输出到设备的字符串参数。TechWeb-技术社区'N/K3l7_+Q+W |
public: // 如果回调函数返回false,缓存对象的_Mystate将被设为BAD,并不再继续写入。
l/F/O"_;cTechWeb-技术社区 typedef bool (__stdcall *_Myof)( const _Elem* );'^6U8}'}&S*B$`6S8X
explicit inline CDebugStreamBuf( _Myof _Outfunc )
;i-z-A)D9^*M7G6N:}(QTechWeb-技术社区 : _Myoutfunc( _Outfunc ){} // 初始化回调函数5q-F(J&{7G9\$R,L
virtual ~CDebugStreamBuf( void ){} // 虚析构函数
9c6I&C+N2J%u,C3_protected: // 每次同步都会刷新缓存中的所有内容1Q'n;Q9i3{2N*d8i
virtual int sync( void ) // 重载sync函数,将在需要输入到设备(同步)时被调用程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码,黑客,安全,技术社区,技术论坛"w/M%t/s6W+x0p4M-S8t*t
{ // 如果无回调函数或缓冲未初始化,返回错误。_Mystate将被设为BAD
/B6y9q2~8g-d if ( _Myoutfunc == 0 || pptr() == 0 ) return -1;
+p"B9] _5E+i)J(itech.techweb.com.cn else if ( _Mysb::pbase() >= _Mysb::epptr() ) return 0;
/{3V0k8x/w([+v2oTechWeb-技术社区 else // 确保缓存可以写入7e9]:i%\$R#C*f K2A+U3[
{ // 将当前写指针的后一位改写为0,如果缓存长度不足将调用overflow执行添加
"N,p%E*e5G*f8R!hTechWeb-技术社区 sputc( _Traits::to_char_type( 0 ) );:w*t'g$n4u5l1B0S+q/H(x
setg( pbase(), pbase(), pptr() ); // 将读指针设为缓存起点tech.techweb.com.cn3n3|6}.I5^"e.^8z)a3M r
seekpos( 0, ios_base::out ); // 将写指针置0以备下次从起点写入
3M$c+^'x;j:X(B"g4z程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码,黑客,安全,技术社区,技术论坛 for ( ; gptr() < egptr(); ) // 遍例tech.techweb.com.cn$p2d*V/y Q1m#S
{ //忽略包括当前指针在内后面的所有0值
%j-Q8B!o4c6e+_ for ( ; !sbumpc(); );'?#r3V4h$p'o+N0\#v*e$M
if ( !_Myoutfunc( gptr() - 1 ) ) return -1; // 输出字符串
%E2v#P"E*j)A#U(? gbump( (int)( find( gptr(), egptr(), // 找到下一个0值
-_(o:d'M'o*Vtech.techweb.com.cn _Traits::to_char_type( 0 ) ) - gptr() + 1 ) );
&i7~1Q8O6z0C(Z!|TechWeb-技术社区 }TechWeb-技术社区'o$e5U0{/w(v:V!j"U%V
}2W$i7{,g&{.S
return 0;程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码,黑客,安全,技术社区,技术论坛1^/~5{&]"b4m3l;f2P
}$a+k'M4J2R%B#t&j0]
protected:TechWeb-技术社区6Q,r0i0@0D*u l%p;G,{
_Myof _Myoutfunc; // 回调函数成员,必须在构造时初始化7B.[7g2_.m.A7S%V8K ]
};
(w!k&?"W'x%}tech.techweb.com.cn
"L4z9r0L,{#J1I;k程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码,黑客,安全,技术社区,技术论坛
*|-j#j6F3Q0C w!y$K1[%Q3p/z9D5G+O)U"@!h
-Q"} `6}4?6g#b第二步:在包含(#include)第一步所选头文件的任意一个代码文件(*.cpp)顶部,包含头文件说明的下面加入如下代码。在这里我们对字符串缓存类的对象进行了初始化,并自己定义了一个回调函数。该回调函数将接受来自缓存类的调式自符串,然后将它输出到VS.net的“输出”窗口。当然,你也可以自己定义这样一个回调函数使字符串写入磁盘映像或SOCKET之类更复杂的设备。 :Y$D#e'^#a1t
程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码,黑客,安全,技术社区,技术论坛8i!N,N,w7W6^
C/C++ code3E4M5^0n a-t e#H'G
bool CALLBACK MyOutputDebugString( LPCTSTR lpText )
-p3U6i'P1Y V(P!d+j{程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码,黑客,安全,技术社区,技术论坛(J0g!Y;L%U
OutputDebugString( lpText );'k,{9D b0d4i
return true;
;x!q0X5Z!\)c)E/Z'E}
!k,M&}9b4V8o,m;h+P#{TechWeb-技术社区CDebugStreamBuf<TCHAR> g_DbgBuf( MyOutputDebugString );
3?8O4P4h(q
!T-o's4X8_&h!Utech.techweb.com.cn3X:Y$~2I$U*J.k1Y:A
%e5[6I([5T.{1P {程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码,黑客,安全,技术社区,技术论坛;j4x's3J(Y7k/E
第三步:在任意一个类的初始化里加入如下代码(两行任选其一):
+c"]*l:{8E;U d p1k%v+s:m1O&q
C/C++ code
0Z*q'X(R2v!}6b-c wcout.rdbuf( &g_DbgBuf ); // Unicode版本
0w*C"R"~"{1B0o8q cout.rdbuf( &g_DbgBuf ); // 非Unicode版本
.H"u#n-I3w;P程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码,黑客,安全,技术社区,技术论坛程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码,黑客,安全,技术社区,技术论坛/_"E%e4O*i#V#{
8B7]4f4_#M9Y/Z9y!?TechWeb-技术社区
8S:{%t3~/B"t"B"N&{之后就可以方便的使用wcout或cout进行GDI程序的调式了,写入wcout或cout的字符串将全部显示在VS.net的“输出”窗口中。
+b+o3[0w'}4Y5PTechWeb-技术社区0j$r&V3J:U;C-}7a4h
使用举例: 程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码,黑客,安全,技术社区,技术论坛6T X-o6^1@1H*O9O5{8w!p"]
$i9n(T3H9] g#j9X-_5]C/C++ codetech.techweb.com.cn*S'X;K8X2J;S9c.l
//
)\+N$D#w u'E#z9t5\程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码,黑客,安全,技术社区,技术论坛 CRect rc;
)q)L1f5]:|%d4k'j-R'q GetWindowRect( &rc );
!h"l%v;c!\ }!?;s"k程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码,黑客,安全,技术社区,技术论坛 wcout << _T("窗口的宽度是:") << rc.Width() <<
#~6z#c$z(Q,yTechWeb-技术社区 _T(",高度是:") << rc.Height() << endl;9N)}0L,a'|+`,y
){5{$^)S1f*Q;P1d9R程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码,黑客,安全,技术社区,技术论坛2Y7Q-H6_4{,P7{,e+G
)|9O4O$h:E.L'K
|