VC 调试 信息输出
2010-08-27 13:52
92 查看
一.前言:
一开始学习C++时,在控制台下写程序做练习,很容易输出程序变量,所以调试很方便。之后学习编写MFC程序,程序运行时要实时查看变量的情况就很麻烦了,虽然有TRACE宏(这个也是后来才知道的),但必须是程序结束后才能查看,而且阅读起来也很费劲。最开始自己写了个简陋的dis()函数(请看本文后面的附录),很简单,几行代码往程序一粘贴,再调用dis函数就可以显示字符串和int变量了。但后面输出的变量会覆盖之前的变量,所以还是不方便。于是一直在寻找一种输出变量更好的方法,偶然的情况下在网上下载了个DebugView.exe(下载),试了一下,就觉爱不释手。TRACE输出的变量实时地显示在DebugView上,给调试带来了更多的方便。本来以为是这已经是终极好方法,谁知又在偶然的情况下,看到一位高手写的一段代码,可以很简单的将变量输出到控制台窗口,比起用DebugView的方法是更甚一筹了。之后自己再做了些研究,不断改进,力求简单傻瓜,终于有了一个较为满意的解决法案了。现在拿出来很大家分享。希望对你有所帮助。
二.把trace函数添加到你的工程:
方法一:把下面的红色字体代码保存为头文件Trace.h,然后在StdAfx.h包含它。
方法二:直接把下面的红色字体代码粘贴在StdAfx.h中。(我个人更倾向于这种方法,方便)
三.使用示例
void CDemoDlg::OnButton1()
{
int a=45; trace(a); //输出int型
double b=67.45; trace(b); //输出double型
TCHAR buf[20]=_T("jacky"); trace(buf); //输出字符串
trace("测试");
trace(_T("测试"));
}
void CDemoDlg::OnButton2()
{
int a=45; double b=67.45;
trace2(a,b);
}
void CDemoDlg::OnButton3()
{
POINT point;
GetCursorPos(&point);
TracePoint(point);
}
void CDemoDlg::OnButton4()
{
RECT rect;
::GetWindowRect(m_hWnd,&rect);
TraceRect(rect);
}
void CDemoDlg::OnButton5()
{
TraceLastError();
}
四.几点说明
1.输出函数有以下几个:
trace(X) //输出1个变量
trace2(X,Y) //输出2个变量
trace3(X,Y,Z) //输出3个变量
trace4(X,Y,Z,W) //输出4个变量
TracePoint(P) //输出坐标型POINT的数据
TraceRect(X) //输出RECT型的数据
TraceLastError()//输出上次错误的代码号
2.几个trace函数都具有自动识别数据类型的功能。
如:
int a=45; trace(a); //输出int型
char str[10]="jacky"; trace(str); //输出字符串
double b=67.45; trace(b); //输出double型
3.用trace()函数直接输出字符串时,可以不添加_T() 或 TEXT() 宏
trace("my test");
trace(_T("my test"));
trace(TEXT("my test"));
以上三个函数输出的都是 “my test”;
4.设置输出窗口的位置和大小。
在OnInitDialog()里添加下面代码:
SetDebugWndPos(HWND_TOPMOST,0,0,400,600);
5.如果想在Release版本中使用trace(),请用"TRACE_WINDOW"代替"#ifdef _DEBUG"中的"_DEBUG"就可以了
6.上面的代码支持Unicode,在VC6和VS2008中编译通过
五.图片预览
![](http://hiphotos.baidu.com/qiujiejia/pic/item/45ce151f55bc4249304e158e.jpg)
六.示例代码下载
trace_Demo.zip (在VC6下编译通过,支持unicode)(请不要直接使用迅雷下载)
trace_Demo_for_VS2008 (在vs2008中编译通过,支持unicode)
七.写应用程序日志
以下这个ftrace() 函数跟上面提到的trace() 函数的用法非常相似,不同点:
1.trace()监视的变量会显示在窗口并且保存在"DebugData.txt"文件中,
而ftrace() 直接保存变量在AppLog.txt中。
2.ftrace()是以追加的方式存入到原有的文件,而trace()每次都会删除原来
DebugData.txt中的数据后再重新保存
3.用法和上面描述的一样,把下面的代码粘贴在StdAfx.h中
八.另一个监视变量的工具
它是高手Paul DiLascia写的,相信会很不错。
http://www.dilascia.com/TraceWin.htm
其他:
vc 调试信息输出
文章出处:飞诺网(www.firnow.com):http://dev.firnow.com/course/3_program/c++/cppjs/20090303/157190.html
1.CDumpContext
该类没有基类。
这个类支持面向流的诊断输出,以人能够阅读的文本。
该类重载了<<操作符。
afxDump是一个预声明的CDumpContext对象,可以方便使用。
该对象只在MFC的Debug版中有效。
可以将调式信息输出到调试输出窗口或调试终端。
// example for afxDump
CPerson myPerson = new CPerson;
// set some fields of the CPerson object...
//..
// now dump the contents
#ifdef _DEBUG
afxDump << "Dumping myPerson:/n";
myPerson->Dump( afxDump );
afxDump << "/n";
#endif
如果想建立一个制定的输出,比如一个制定的errlog文件。
我们可以自己生成一个CDumpContext对象。
方法如下:
CFile f;
if( !f.Open( "dump.txt", CFile::modeCreate | CFile::modeWrite ) ) {
afxDump << "Unable to open file" << "/n";
exit( 1 );
}
CDumpContext dc( &f );
2.TRACE
这个宏可以在DEBUG过程中,方便的跟踪程序中的变量的值。
在Debug环境中,TRACE宏输出到afxDump对象中。
在Release环境中,它不起作用。
TRACE一次限制512个字符,包括结束的NULL字符。
如果超过将引发ASSERT。
例:
int i = 1;
char sz[] = "one";
TRACE( "Integer = %d, String = %s/n", i, sz );
// Output: 'Integer = 1, String = one'
同时,还有TRACE0,TRACE1,TRACE2,TRACE3等宏。
数字代表宏中的参数数。
// example for TRACE0
TRACE0( "Start Dump of MyClass members:" );
// example for TRACE1
int i = 1;
TRACE1( "Integer = %d/n", i );
// Output: 'Integer = 1'
// example for TRACE2
int i = 1;
char sz[] = "one";
TRACE2( "Integer = %d, String = %s/n", i, sz );
// Output: 'Integer = 1, String = one'
3.void AfxDump( const CObject* pOb )
该函数调用对象的Dump成员函数,将信息输出到afxDump制定的位置。
最好不要在程序中调用该函数,而使用对象的Dump函数。
4.virtual void Dump( CDumpContext& dc ) const;
是CObjec的成员函数,将对象的内容输出到一个CDumpContext对象。
写自定义类的时候,应该重写Dump函数,来提供诊断服务。
重写的Dump函数中一般会先调用基类的Dump函数,后输出数据成员。
CObject::Dump输出类名,如果你的类用了IMPLEMENT_DYNAMIC或IMPLEMENT_SERIAL宏。
例:
class CPerson : public CObject
{
public:
//声明
#ifdef _DEBUG
virtual void Dump( CDumpContext& dc ) const;
#endif
CString m_firstName;
CString m_lastName;
// etc. ...
};
//实现
#ifdef _DEBUG
void CPerson::Dump( CDumpContext& dc ) const
{
// call base class function first
CObject::Dump( dc );
// now do the stuff for our specific class
dc << "last name: " << m_lastName << "/n"
<< "first name: " << m_firstName << "/n";
}
#endif
//调用
CPerson person;
#ifdef _DEBUG
CFile f;
if( !f.Open( "c://dump.txt", CFile::modeCreate | CFile::modeWrite ) ) {
afxDump << "Unable to open file" << "/n";
exit( 1 );
}
CDumpContext dc( &f );
person.Dump(dc);
dc<<"test dump output";
#endif
在较复杂的程序中,我们可以采用上述方法,
在调试程序的过程中,输出自己想要的数据和信息。
还是较为方便和简单的方法的。
文章出处:飞诺网(www.firnow.com):http://dev.firnow.com/course/3_program/c++/cppjs/20090303/157190.html
一开始学习C++时,在控制台下写程序做练习,很容易输出程序变量,所以调试很方便。之后学习编写MFC程序,程序运行时要实时查看变量的情况就很麻烦了,虽然有TRACE宏(这个也是后来才知道的),但必须是程序结束后才能查看,而且阅读起来也很费劲。最开始自己写了个简陋的dis()函数(请看本文后面的附录),很简单,几行代码往程序一粘贴,再调用dis函数就可以显示字符串和int变量了。但后面输出的变量会覆盖之前的变量,所以还是不方便。于是一直在寻找一种输出变量更好的方法,偶然的情况下在网上下载了个DebugView.exe(下载),试了一下,就觉爱不释手。TRACE输出的变量实时地显示在DebugView上,给调试带来了更多的方便。本来以为是这已经是终极好方法,谁知又在偶然的情况下,看到一位高手写的一段代码,可以很简单的将变量输出到控制台窗口,比起用DebugView的方法是更甚一筹了。之后自己再做了些研究,不断改进,力求简单傻瓜,终于有了一个较为满意的解决法案了。现在拿出来很大家分享。希望对你有所帮助。
二.把trace函数添加到你的工程:
方法一:把下面的红色字体代码保存为头文件Trace.h,然后在StdAfx.h包含它。
方法二:直接把下面的红色字体代码粘贴在StdAfx.h中。(我个人更倾向于这种方法,方便)
#include <afxwin.h> // MFC core and standard components #include <afxext.h> // MFC extensions #include <afxdisp.h> // MFC Automation classes #include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls #ifndef _AFX_NO_AFXCMN_SUPPORT #include <afxcmn.h> // MFC support for Windows Common Controls #endif // _AFX_NO_AFXCMN_SUPPORT /**************************************************************************** trace function 功能:输出调试变量 操作:在StdAfx.h加入以下代码(或者放在一个独立的头文件中),之后在需要的地方调用trace()函数就可以监视变量 说明: 1.如果想在Release版本中使用trace(),用"TRACE_WINDOW"代替"#ifdef _DEBUG"中的"_DEBUG" 2.可调用 SetDebugWndPos(HWND_TOPMOST,0,0,400,600); 设置输出窗口的位置以及是否置顶窗口 3.所有输出的变量都会保存在工程目录下的"DebugData.txt"文件,以方便查看 4.更详细介绍请访问:http://hi.baidu.com/qiujiejia/blog/item/e43943187fc1f90e34fa4176.html 5.由于在下水平有限,若有错误,还望海涵。若有问题或建议,请email我:qiujiejia@gmail.com ****************************************************************************/ //如果想在Release版本中使用trace(),用"TRACE_WINDOW"代替"#ifdef _DEBUG"中的"_DEBUG" #define TRACE_WINDOW #define IndexLength 6 //设置序号的长度 #ifdef _DEBUG #include <sstream> #include <string> //设置类成为通用版本 #ifdef _UNICODE #define tstring wstring #define tostringstream wostringstream #define titoa _itow #else #define tstring string #define tostringstream ostringstream #define titoa _itoa #endif class DEBUG_WINDOW { private: TCHAR WindowText[100]; HANDLE hOut; //控制台句柄 FILE* fp; //输出文件句柄 public: DEBUG_WINDOW(TCHAR* WindowName,char* FileName,int cx,int cy) { _tcsncpy(WindowText,WindowName,99); AllocConsole();//分配 SetConsoleTitle(WindowName); //窗口标题 hOut = GetStdHandle(STD_OUTPUT_HANDLE);//指明句柄为标准输出HANDLE COORD co = {cx,cy}; SetConsoleScreenBufferSize(hOut, co);//指明缓冲区大小 fp = fopen(FileName,"w");//打开由于保存数据文件DebugData.txt, } ~DEBUG_WINDOW() { fclose(fp); } void PrintString(TCHAR* OutputStr,int nMax) { DWORD cCharsWritten; WriteConsole(hOut,OutputStr,nMax,&cCharsWritten, NULL); #ifdef _UNICODE //先进行转换 char* buff = new char[nMax*2+1]; memset(buff,0,nMax*2+1); setlocale(LC_ALL,".936"); int nChars = wcstombs(buff,OutputStr,nMax*2+1); setlocale(LC_ALL,"C"); fwrite(buff,1,nChars,fp); delete buff; #else fwrite(OutputStr,1,nMax,fp); #endif } void SetWindowPos(HWND hWndInsertAfter=HWND_TOPMOST,int x=0,int y=0,int cx=200,int cy=200) { ::SetWindowPos(::FindWindow(NULL,WindowText),hWndInsertAfter,x,y,cx,cy,NULL); } template<class T> void Trace(TCHAR* ArgName,T a) { //ArgName就是trace() 括号里的所有东西,可能是"jacky" or _T("jacky") or TEXT("jacky") if(*ArgName=='"') //*****************情况为 "jacky" { int len=_tcslen(ArgName+1); TCHAR* p=new TCHAR[len]; _tcsncpy(p,ArgName+1,len-1); p[len-1]='/0'; //最后一个置0 PrintString(p,len-1); delete p; } else if ( *(ArgName+2)=='(' ) //******情况为 _T("jacky") { int len=_tcslen(ArgName+4)-1; TCHAR* p=new TCHAR[len]; _tcsncpy(p,ArgName+4,len-1); p[len-1]='/0'; //最后一个置0 PrintString(p,len-1); delete p; } else if ( *(ArgName+4)=='(' ) //******情况为 TEXT("jacky") { int len=_tcslen(ArgName+6)-1; TCHAR* p=new TCHAR[len]; _tcsncpy(p,ArgName+6,len-1); p[len-1]='/0'; //最后一个置0 PrintString(p,len-1); delete p; } else //是一个变量名称 { PrintString(ArgName,_tcslen(ArgName)); //变量名没有分号 std::tostringstream FormatString; FormatString<<TEXT("=")<<a; std::tstring OutStr=FormatString.str(); PrintString((TCHAR*)OutStr.c_str(),OutStr.length()); } } }; //实例化一个对象,要定义为static,否则通不过编译 static DEBUG_WINDOW DebugWnd(_T("Debug Window"),"DebugData.txt",400,400); static int DebugItemIndex=0; static TCHAR iBuf[20]; #define AddIndex() {DebugWnd.PrintString(titoa(DebugItemIndex++,iBuf,10),IndexLength);} #define SetDebugWndPos(X,Y,Z,W,T) {DebugWnd.SetWindowPos(X,Y,Z,W,T);} #define trace(X) { AddIndex();DebugWnd.Trace(TEXT(#X),X); DebugWnd.PrintString(_T("/n"),1); } #define trace2(X,Y) { AddIndex();DebugWnd.Trace(TEXT(#X),X); DebugWnd.PrintString(_T(" "),3); / DebugWnd.Trace(TEXT(#Y),Y); DebugWnd.PrintString(_T("/n"),1); } #define trace3(X,Y,Z) { AddIndex();DebugWnd.Trace(TEXT(#X),X); DebugWnd.PrintString(_T(" "),3); / DebugWnd.Trace(TEXT(#Y),Y); DebugWnd.PrintString(_T(" "),3); / DebugWnd.Trace(TEXT(#Z),Z); DebugWnd.PrintString(_T("/n"),1); } #define trace4(X,Y,Z,W) { AddIndex();DebugWnd.Trace(TEXT(#X),X); DebugWnd.PrintString(_T(" "),3); / DebugWnd.Trace(TEXT(#Y),Y); DebugWnd.PrintString(_T(" "),3); / DebugWnd.Trace(TEXT(#Z),Z); DebugWnd.PrintString(_T(" "),3); / DebugWnd.Trace(TEXT(#W),W); DebugWnd.PrintString(_T("/n"),1); } #define TracePoint(P) trace2(P.x,P.y) #define TraceRect(X) trace4(X.left,X.top,X.right,X.bottom) #define TraceLastError(){ AddIndex(); DebugWnd.Trace(_T("System Error Codes:"),GetLastError()); DebugWnd.PrintString(_T("/n"),1); } #else #define SetDebugWndPos(X,Y,Z,W,T) #define trace(X) #define trace2(X,Y) #define trace3(X,Y,Z) #define trace4(X,Y,Z,W) #define TracePoint(P) #define TraceRect(X) #define TraceLastError() #endif //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_STDAFX_H__EE32DF26_4082_4291_A7C6_3A35739DAD97__INCLUDED_) |
void CDemoDlg::OnButton1()
{
int a=45; trace(a); //输出int型
double b=67.45; trace(b); //输出double型
TCHAR buf[20]=_T("jacky"); trace(buf); //输出字符串
trace("测试");
trace(_T("测试"));
}
void CDemoDlg::OnButton2()
{
int a=45; double b=67.45;
trace2(a,b);
}
void CDemoDlg::OnButton3()
{
POINT point;
GetCursorPos(&point);
TracePoint(point);
}
void CDemoDlg::OnButton4()
{
RECT rect;
::GetWindowRect(m_hWnd,&rect);
TraceRect(rect);
}
void CDemoDlg::OnButton5()
{
TraceLastError();
}
四.几点说明
1.输出函数有以下几个:
trace(X) //输出1个变量
trace2(X,Y) //输出2个变量
trace3(X,Y,Z) //输出3个变量
trace4(X,Y,Z,W) //输出4个变量
TracePoint(P) //输出坐标型POINT的数据
TraceRect(X) //输出RECT型的数据
TraceLastError()//输出上次错误的代码号
2.几个trace函数都具有自动识别数据类型的功能。
如:
int a=45; trace(a); //输出int型
char str[10]="jacky"; trace(str); //输出字符串
double b=67.45; trace(b); //输出double型
3.用trace()函数直接输出字符串时,可以不添加_T() 或 TEXT() 宏
trace("my test");
trace(_T("my test"));
trace(TEXT("my test"));
以上三个函数输出的都是 “my test”;
4.设置输出窗口的位置和大小。
在OnInitDialog()里添加下面代码:
SetDebugWndPos(HWND_TOPMOST,0,0,400,600);
5.如果想在Release版本中使用trace(),请用"TRACE_WINDOW"代替"#ifdef _DEBUG"中的"_DEBUG"就可以了
6.上面的代码支持Unicode,在VC6和VS2008中编译通过
五.图片预览
![](http://hiphotos.baidu.com/qiujiejia/pic/item/45ce151f55bc4249304e158e.jpg)
六.示例代码下载
trace_Demo.zip (在VC6下编译通过,支持unicode)(请不要直接使用迅雷下载)
trace_Demo_for_VS2008 (在vs2008中编译通过,支持unicode)
七.写应用程序日志
以下这个ftrace() 函数跟上面提到的trace() 函数的用法非常相似,不同点:
1.trace()监视的变量会显示在窗口并且保存在"DebugData.txt"文件中,
而ftrace() 直接保存变量在AppLog.txt中。
2.ftrace()是以追加的方式存入到原有的文件,而trace()每次都会删除原来
DebugData.txt中的数据后再重新保存
3.用法和上面描述的一样,把下面的代码粘贴在StdAfx.h中
/**************************************************************************** ftrace() 函数 功能:将要监视的状况写入应用程序事件日志,方便了解程序的运行状况。 操作:在StdAfx.h加入以下代码(或者放在一个独立的头文件中),之后在需要的地方调用ftrace()函数就可以监视变量 说明: 1.希望所有的ftrace函数无效,只需要注释掉“#define WRITE_DATA” 就可以了。 2.所有输出的数据都会保存在程序目录下的"AppLog.txt"文件,数据以追加的方式存入文件。 3.更详细介绍请访问:http://hi.baidu.com/qiujiejia/blog/item/e43943187fc1f90e34fa4176.html 4.由于在下水平有限,若有错误,还望海涵。若有问题,请email我:qiujiejia@gmail.com ****************************************************************************/ //注释掉这一句会使所有ftrace()函数无效 #define WRITE_DATA #ifdef WRITE_DATA #include <sstream> #include <string> //设置类成为通用版本 #ifdef _UNICODE #define tstring wstring #define tostringstream wostringstream #else #define tstring string #define tostringstream ostringstream #endif class WRITE_DATA_TO_FILE { private: FILE* fp; public: WRITE_DATA_TO_FILE(char* FileName) {fp=fopen(FileName,"a+");} ~WRITE_DATA_TO_FILE(){ fclose(fp); } void PrintString(TCHAR* OutputStr,int nMax) { #ifdef _UNICODE //先进行转换 char* buff = new char[nMax*2+1]; memset(buff,0,nMax*2+1); setlocale(LC_ALL,".936"); int nChars = wcstombs(buff,OutputStr,nMax*2+1); setlocale(LC_ALL,"C"); fwrite(buff,1,nChars,fp); delete buff; #else fwrite(OutputStr,1,nMax,fp); #endif } template<class T> void Trace(TCHAR* ArgName,T a) { //ArgName就是trace() 括号里的所有东西,可能是"jacky" or _T("jacky") or TEXT("jacky") if(*ArgName=='"') //*****************情况为 "jacky" { int len=_tcslen(ArgName+1); TCHAR* p=new TCHAR[len]; _tcsncpy(p,ArgName+1,len-1); p[len-1]='/0'; //最后一个置0 PrintString(p,len-1); delete p; } else if ( *(ArgName+2)=='(' ) //******情况为 _T("jacky") { int len=_tcslen(ArgName+4)-1; TCHAR* p=new TCHAR[len]; _tcsncpy(p,ArgName+4,len-1); p[len-1]='/0'; //最后一个置0 PrintString(p,len-1); delete p; } else if ( *(ArgName+4)=='(' ) //******情况为 TEXT("jacky") { int len=_tcslen(ArgName+6)-1; TCHAR* p=new TCHAR[len]; _tcsncpy(p,ArgName+6,len-1); p[len-1]='/0'; //最后一个置0 PrintString(p,len-1); delete p; } else //是一个变量名称 { PrintString(ArgName,_tcslen(ArgName)); //变量名没有分号 std::tostringstream FormatString; FormatString<<TEXT("=")<<a; std::tstring OutStr=FormatString.str(); PrintString((TCHAR*)OutStr.c_str(),OutStr.length()); } } }; //实例化一个对象 static WRITE_DATA_TO_FILE obj("AppLog.txt"); #define ftrace(X) { obj.Trace(TEXT(#X),X); obj.PrintString(_T("/n"),1); } #define ftrace2(X,Y) { obj.Trace(TEXT(#X),X); obj.PrintString(_T(" "),3); / obj.Trace(TEXT(#Y),Y); obj.PrintString(_T("/n"),1); } #define ftrace3(X,Y,Z) { obj.Trace(TEXT(#X),X); obj.PrintString(_T(" "),3); / obj.Trace(TEXT(#Y),Y); obj.PrintString(_T(" "),3); / obj.Trace(TEXT(#Z),Z); obj.PrintString(_T("/n"),1); } #define ftrace4(X,Y,Z,W) { obj.Trace(TEXT(#X),X); obj.PrintString(_T(" "),3); / obj.Trace(TEXT(#Y),Y); obj.PrintString(_T(" "),3); / obj.Trace(TEXT(#Z),Z); obj.PrintString(_T(" "),3); / obj.Trace(TEXT(#W),W); obj.PrintString(_T("/n"),1); } #define fTracePoint(P) ftrace2(P.x,P.y) #define fTraceRect(X) ftrace4(X.left,X.top,X.right,X.bottom) #define fTraceLastError(){ obj.Trace(_T("System Error Codes:"),GetLastError()); obj.PrintString(_T("/n"),1); } #else #define ftrace(X) #define ftrace2(X,Y) #define ftrace3(X,Y,Z) #define ftrace4(X,Y,Z,W) #define fTracePoint(P) #define fTraceRect(X) #define fTraceLastError() #endif |
它是高手Paul DiLascia写的,相信会很不错。
http://www.dilascia.com/TraceWin.htm
其他:
vc 调试信息输出
文章出处:飞诺网(www.firnow.com):http://dev.firnow.com/course/3_program/c++/cppjs/20090303/157190.html
1.CDumpContext
该类没有基类。
这个类支持面向流的诊断输出,以人能够阅读的文本。
该类重载了<<操作符。
afxDump是一个预声明的CDumpContext对象,可以方便使用。
该对象只在MFC的Debug版中有效。
可以将调式信息输出到调试输出窗口或调试终端。
// example for afxDump
CPerson myPerson = new CPerson;
// set some fields of the CPerson object...
//..
// now dump the contents
#ifdef _DEBUG
afxDump << "Dumping myPerson:/n";
myPerson->Dump( afxDump );
afxDump << "/n";
#endif
如果想建立一个制定的输出,比如一个制定的errlog文件。
我们可以自己生成一个CDumpContext对象。
方法如下:
CFile f;
if( !f.Open( "dump.txt", CFile::modeCreate | CFile::modeWrite ) ) {
afxDump << "Unable to open file" << "/n";
exit( 1 );
}
CDumpContext dc( &f );
2.TRACE
这个宏可以在DEBUG过程中,方便的跟踪程序中的变量的值。
在Debug环境中,TRACE宏输出到afxDump对象中。
在Release环境中,它不起作用。
TRACE一次限制512个字符,包括结束的NULL字符。
如果超过将引发ASSERT。
例:
int i = 1;
char sz[] = "one";
TRACE( "Integer = %d, String = %s/n", i, sz );
// Output: 'Integer = 1, String = one'
同时,还有TRACE0,TRACE1,TRACE2,TRACE3等宏。
数字代表宏中的参数数。
// example for TRACE0
TRACE0( "Start Dump of MyClass members:" );
// example for TRACE1
int i = 1;
TRACE1( "Integer = %d/n", i );
// Output: 'Integer = 1'
// example for TRACE2
int i = 1;
char sz[] = "one";
TRACE2( "Integer = %d, String = %s/n", i, sz );
// Output: 'Integer = 1, String = one'
3.void AfxDump( const CObject* pOb )
该函数调用对象的Dump成员函数,将信息输出到afxDump制定的位置。
最好不要在程序中调用该函数,而使用对象的Dump函数。
4.virtual void Dump( CDumpContext& dc ) const;
是CObjec的成员函数,将对象的内容输出到一个CDumpContext对象。
写自定义类的时候,应该重写Dump函数,来提供诊断服务。
重写的Dump函数中一般会先调用基类的Dump函数,后输出数据成员。
CObject::Dump输出类名,如果你的类用了IMPLEMENT_DYNAMIC或IMPLEMENT_SERIAL宏。
例:
class CPerson : public CObject
{
public:
//声明
#ifdef _DEBUG
virtual void Dump( CDumpContext& dc ) const;
#endif
CString m_firstName;
CString m_lastName;
// etc. ...
};
//实现
#ifdef _DEBUG
void CPerson::Dump( CDumpContext& dc ) const
{
// call base class function first
CObject::Dump( dc );
// now do the stuff for our specific class
dc << "last name: " << m_lastName << "/n"
<< "first name: " << m_firstName << "/n";
}
#endif
//调用
CPerson person;
#ifdef _DEBUG
CFile f;
if( !f.Open( "c://dump.txt", CFile::modeCreate | CFile::modeWrite ) ) {
afxDump << "Unable to open file" << "/n";
exit( 1 );
}
CDumpContext dc( &f );
person.Dump(dc);
dc<<"test dump output";
#endif
在较复杂的程序中,我们可以采用上述方法,
在调试程序的过程中,输出自己想要的数据和信息。
还是较为方便和简单的方法的。
文章出处:飞诺网(www.firnow.com):http://dev.firnow.com/course/3_program/c++/cppjs/20090303/157190.html
相关文章推荐
- VC2010 MFC中实现printf调试功能,即MFC程序利用控制台输出调试信息
- vc 调试信息输出
- VC2010 MFC中实现printf调试功能,即MFC程序利用控制台输出调试信息
- VC调试信息的输出
- VC调试时输出调试信息到Debug窗口
- VC2010 MFC中实现printf调试功能,即MFC程序利用控制台输出调试信息
- VC调试信息输出 TRACE宏
- win32/vc 程序调试信息命令行输出
- VC2010 MFC中实现printf调试功能,即MFC程序利用控制台输出调试信息。
- vc输出调试信息的方法
- 2012-08-02 15:07 VC++ 往输出窗口打印调试信息调用函数
- VC2010 MFC中实现printf调试功能,即MFC程序利用控制台输出调试信息。
- vc,输出调试信息
- vc++ 调试信息输出 打印调试信息 .
- VC MFC如何使用Console输出调试信息..
- VC2010 MFC中实现printf调试功能,即MFC程序利用控制台输出调试信息
- 调试程序时在不中断程序的情况下输出函数调用信息(Mac OS,Linux & Windows)
- Windows程序中增加consle窗显示printf输出调试信息的一种方法
- [iphonedev] 一句话总结.GDB为啥不输出调试信息了?
- c++输出调试信息到vs中的输出窗口