【原创】一个很好用的调试辅助类,使用需要一定C++基础,请多提建议,UP有分!

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

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


#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之类更复杂的设备。

bool CALLBACK MyOutputDebugString( LPCTSTR lpText )
{
OutputDebugString( lpText );
return true;
}
CDebugStreamBuf<TCHAR> g_DbgBuf( MyOutputDebugString );


第三步:在任意一个类的初始化里加入如下代码(两行任选其一):

wcout.rdbuf( &g_DbgBuf ); // Unicode版本
cout.rdbuf( &g_DbgBuf ); // 非Unicode版本

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

使用举例

//
CRect rc;
GetWindowRect( &rc );
wcout << _T("窗口的宽度是:") << rc.Width() <<
_T(",高度是:") << rc.Height() << endl;

...全文
3891 222 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
222 条回复
切换为时间正序
请发表友善的回复…
发表回复
佛光寺 2012-07-11
  • 打赏
  • 举报
回复
up!up!up!up!up!up!
wangzhenghua123 2012-04-06
  • 打赏
  • 举报
回复
努力学习
早点看明白
cvanchen 2012-02-23
  • 打赏
  • 举报
回复
up一下
  • 打赏
  • 举报
回复
up biaoji
etora 2012-02-21
  • 打赏
  • 举报
回复
学习了~~~
_暮落_ 2012-02-20
  • 打赏
  • 举报
回复
up大神
fervorman 2012-01-30
  • 打赏
  • 举报
回复
mark
强人
cqbibby 2012-01-30
  • 打赏
  • 举报
回复
必须up 跟楼主学习~
  • 打赏
  • 举报
回复
高。

嫖过。

tobyzhang2005 2011-06-13
  • 打赏
  • 举报
回复
up nafen
xiongyu2006 2011-05-30
  • 打赏
  • 举报
回复
学习了!
na5120 2011-03-19
  • 打赏
  • 举报
回复
  int a[6][6];
int (*p)[5];
p=a;
printf("a_ptr = %#p,p_ptr = %#p \n",&a[4][2],&p[4][2]);
printf("%p,%d",&p[4][2]-&a[4][2],&p[4][2]-&a[4][2]);


cmlr_ 2010-12-23
  • 打赏
  • 举报
回复
看到一堆下划线,标准库风格啊
一堆模板,atl风格啊.

看上去就觉得晕.
jkc_cpp 2010-12-16
  • 打赏
  • 举报
回复
专业路过~
yaneng 2010-11-06
  • 打赏
  • 举报
回复
看不太懂,坐下来慢慢研究
yaneng 2010-11-06
  • 打赏
  • 举报
回复
学习中。。。
勇敢的搬砖人 2010-05-26
  • 打赏
  • 举报
回复
linfangrong 2010-05-09
  • 打赏
  • 举报
回复
up完再看~!!= =!天啊,太长了!
www13452 2010-05-04
  • 打赏
  • 举报
回复
up 呵呵
iwollbs 2010-01-23
  • 打赏
  • 举报
回复
好好学习下
加载更多回复(200)

65,186

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧