一个很好用的调试辅助类,使用需要一定C++基础

     很多时候我们需要把程序运行过程中的一些临时变量显示出来,一般我们可以通过wcout或cout类将调式信息输出到控制台。但有时我们需要将调试信息输出到别的地方,比如VS.net的“输出”窗口就比较麻烦了,可能需要频繁的在字符串和数字间相互转换,这对于C++程序员来说可真是一场恶梦。下面提出一种方案,可以很好的解决这个问题。即利用替换wcout或cout的内部字符串缓存的方法,使写入到wcout或cout的字符串转写到其它的设备中。 

第一步:在你整个工程的头文件,比如stdafx.h里的下面加入以下代码。这是用于wcout或cout的字符串缓存类。 

C/C++ code
    
    
#include < iostream > #include < algorithm > #include < sstream > #include < tchar.h > using namespace std; template < class _Elem, class _Traits = char_traits < _Elem > > class CDebugStreamBuf : public basic_stringbuf < _Elem, _Traits > { // 回调函数接受一个准备输出到设备的字符串参数。 public : // 如果回调函数返回false,缓存对象的_Mystate将被设为BAD,并不再继续写入。 typedef bool (__stdcall * _Myof)( const _Elem * ); explicit inline CDebugStreamBuf( _Myof _Outfunc ) : _Myoutfunc( _Outfunc ){} // 初始化回调函数 virtual ~ CDebugStreamBuf( void ){} // 虚析构函数 protected : // 每次同步都会刷新缓存中的所有内容 virtual int sync( void ) // 重载sync函数,将在需要输入到设备(同步)时被调用 { // 如果无回调函数或缓冲未初始化,返回错误。_Mystate将被设为BAD if ( _Myoutfunc == 0 || pptr() == 0 ) return - 1 ; else if ( _Mysb::pbase() >= _Mysb::epptr() ) return 0 ; else // 确保缓存可以写入 { // 将当前写指针的后一位改写为0,如果缓存长度不足将调用overflow执行添加 sputc( _Traits::to_char_type( 0 ) ); setg( pbase(), pbase(), pptr() ); // 将读指针设为缓存起点 seekpos( 0 , ios_base:: out ); // 将写指针置0以备下次从起点写入 for ( ; gptr() < egptr(); ) // 遍例 { // 忽略包括当前指针在内后面的所有0值 for ( ; ! sbumpc(); ); if ( ! _Myoutfunc( gptr() - 1 ) ) return - 1 ; // 输出字符串 gbump( ( int )( find( gptr(), egptr(), // 找到下一个0值 _Traits::to_char_type( 0 ) ) - gptr() + 1 ) ); } } return 0 ; } protected : _Myof _Myoutfunc; // 回调函数成员,必须在构造时初始化 };


第二步:在包含(#include)第一步所选头文件的任意一个代码文件(*.cpp)顶部,包含头文件说明的下面加入如下代码。在这里我们对字符串缓存类的对象进行了初始化,并自己定义了一个回调函数。该回调函数将接受来自缓存类的调式自符串,然后将它输出到VS.net的“输出”窗口。当然,你也可以自己定义这样一个回调函数使字符串写入磁盘映像或SOCKET之类更复杂的设备。 
C/C++ code
    
    
bool CALLBACK MyOutputDebugString( LPCTSTR lpText ) { OutputDebugString( lpText ); return true ; } CDebugStreamBuf < TCHAR > g_DbgBuf( MyOutputDebugString );


第三步:在任意一个类的初始化里加入如下代码(两行任选其一): 
C/C++ code
    
    
wcout.rdbuf( & g_DbgBuf ); // Unicode版本 cout.rdbuf( & g_DbgBuf ); // 非Unicode版本

之后就可以方便的使用wcout或cout进行GDI程序的调式了,写入wcout或cout的字符串将全部显示在VS.net的“输出”窗口中。 

使用举例: 
C/C++ code
    
    
// CRect rc; GetWindowRect( & rc ); wcout << _T( " 窗口的宽度是: " ) << rc.Width() << _T( " ,高度是: " ) << rc.Height() << endl;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值