将之前的内存查看单元小幅修改,加上文件操作和计时,组成了一个自用debug单元,使用方法如示例。

此单元便捷之处在于直接将#define DEBUG注释掉而无需改动源码,即可取消debug模式。

#define DEBUG stdi|fileo
#include "debug.h"
using namespace debug;
int main()
{
	char str[] = "jiji";
	println("this is a %s", str);
}

// mem.h
#ifndef __MEM_H #define __MEM_H #include <stdio.h> #ifndef MEM_DEF_LENGTH #define MEM_DEF_LENGTH (0x80) #endif #include <windows.h> #define BLACK (0) #define BLUE (1) #define GREEN (2) #define RED (4) #define YELLOW (RED|GREEN) #define CYAN (GREEN|BLUE) #define MAGENTA (BLUE|RED) #define WHITE (RED|GREEN|BLUE) #define HL (8) #ifndef HighlightFG #define HighlightFG (WHITE|HL) #endif #ifndef HighlightBG #define HighlightBG (BLACK) #endif void memdispex(FILE* fp, char *srcptr, int size, int len); #include "mem.cpp" #endif
// mem.cpp
void memdispex(FILE* fp, char *srcptr, int size, int len)
{
	char *p, *pos;
	CONSOLE_SCREEN_BUFFER_INFO csbi;
	GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
	fprintf(fp, "\n");
	for (pos = (char *)((unsigned int)srcptr & 0xFFFFFFF0);
		pos < srcptr + len; pos += 0x10){
		fprintf(fp, "%06X:  ", pos);
		for (p = pos; p < pos + 16; ++p){
			if (p >= srcptr && p < srcptr + size){
				SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
					(HighlightFG) | (HighlightBG) << 4);
			}
			if (p < srcptr || p >= srcptr + len)
				fprintf(fp, "   ");
			else if (p == pos + 7)
				fprintf(fp, "%02X-", *p & 0xFF);
			else
				fprintf(fp, "%02X ", *p & 0xFF);
			SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
				csbi.wAttributes);
		}
		fprintf(fp, "  ");
		for (p = pos; p < pos + 16; ++p){
			if (p >= srcptr && p < srcptr + size){
				SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
					(HighlightFG) | (HighlightBG) << 4);
			}
			if (p < srcptr || p >= srcptr + len)
				fprintf(fp, " ");
			else if (*p < 0x80 && *p >= 0x20)
				fprintf(fp, "%c", *p & 0xFF);
			else
				fprintf(fp, ".");
			SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
				csbi.wAttributes);
		}
		fprintf(fp, "\n");
	}
}
// timer.h
#include <ctime>

class TimerBase
{
private:
    int _start, _result;
public:
    inline void start()
    {
		_result = 0;
        _start = clock();
    }

    inline void resume()
    {
		_start = clock();
	}

	inline int pause()
	{
		return _result += clock() - _start;
	}

    inline int stop()
    {
        return _result += clock() - _start;
    }

    inline double second()
    {
        return (double)_result / 1000;
    }

    inline int tick()
    {
        return _result;
    }
};
// debug.h
#ifndef __DEBUG_H
#define __DEBUG_H

#include <cstdio>
#include <cstdarg>
#include "mem/mem.h"
#include "timer/timer.h"

namespace debug {
	#define stdi		(1)
	#define filei		(2)

	#define stdo		(4)
	#define fileo		(8)

	#define stde		(16)

	#define stdio		(stdi|stdo)
	#define fileio		(filei|fileo)

	#undef __CONFIRM_FILE_INPUT
	#undef __CONFIRM_FILE_OUTPUT

	#ifdef DEBUG
		#if ((DEBUG) & filei) > 0
			#define __CONFIRM_FILE_INPUT
			#ifndef INPUT
				#define INPUT "input.txt"
			#endif
		#endif
		#if ((DEBUG) & fileo) > 0
			#define __CONFIRM_FILE_OUTPUT
			#ifndef OUTPUT
				#define OUTPUT "output.txt"
			#endif
		#endif
	#endif	

	class DebugFileBase
	{
	public:
		static FILE* fp[256];
	};

	FILE* DebugFileBase::fp[256] = {};

	class FileInitializer: protected DebugFileBase
	{
	public:
		FileInitializer();
		~FileInitializer();
	} file_initializer;

	// IOBase

	class InputMethod: protected DebugFileBase
	{
	public:
		InputMethod();
		virtual inline void set_device(int);
	protected:
		int device;
	};

	class OutputMethod: protected DebugFileBase
	{
	public:
		OutputMethod();
		virtual inline void set_device(int);
	protected:
		int device;
	};

	// Input Method

	class Scan: public InputMethod
	{
	public:
		inline int operator ()(const char* format, ...);
	} scan;

	// Output Method

	class Print: public OutputMethod
	{
	public:
		inline int operator ()(const char* format, ...);
	} print;

	class Println: public OutputMethod
	{
	public:
		inline int operator ()(const char* format, ...);
	} println;

	// MemDisplay Method

	class Display: public OutputMethod
	{
	public:
		template <typename T>
		inline void operator ()(const T&, const int len = (MEM_DEF_LENGTH));
	} display;

	class DisplayFixed: public OutputMethod
	{
	public:
		template <typename T>
		inline void operator ()(const T&);
	} display_fixed;

	class DisplayAddr: public OutputMethod
	{
	public:
		template <typename T>
		inline void operator ()(const T&, const int len = (MEM_DEF_LENGTH));
	} display_addr;

	// Timer

	class Timer: public TimerBase
	{
	public:
		inline int halt();
	} timer;
}

#include "debug.cpp"

#endif
// debug.cpp
debug::FileInitializer::FileInitializer()
{
	fp[stdi] = stdin;
	fp[stdo] = stdout;
	fp[stde] = stderr;
	#ifdef __CONFIRM_FILE_INPUT
		fp[filei] = fopen(INPUT, "r");
	#endif
	#ifdef __CONFIRM_FILE_OUTPUT
		fp[fileo] = fopen(OUTPUT, "w");
	#endif
}

debug::FileInitializer::~FileInitializer()
{
	#ifdef __CONFIRM_FILE_INPUT
		fclose(fp[filei]);
	#endif
	#ifdef __CONFIRM_FILE_OUTPUT
    	fclose(fp[fileo]);
	#endif
}

debug::InputMethod::InputMethod()
{
	#ifdef __CONFIRM_FILE_INPUT
		device = filei;
	#else
		device = stdi;
	#endif
}

inline void debug::InputMethod::set_device(int tag)
{
	device = tag & filei ? filei : stdi;
}

debug::OutputMethod::OutputMethod()
{
	#ifdef __CONFIRM_FILE_OUTPUT
		device = fileo;
	#else
		#ifdef DEBUG
			#if (DEBUG & stde) > 0
				device = stde;
			#else
				device = stdo;
			#endif
		#else
			device = stdo;
		#endif
	#endif
}

inline void debug::OutputMethod::set_device(int tag)
{
	device = tag & fileo ? fileo :
		tag & stde ? stde : stdo;
}

inline int debug::Scan::operator ()(const char* format, ...)
{
	#ifdef DEBUG
		va_list args;
		va_start(args, format);
		return vfscanf(fp[device], format, args);
	#else
		return 0;
	#endif
}

inline int debug::Print::operator ()(const char* format, ...)
{
	#ifdef DEBUG
		va_list args;
		va_start(args, format);
		int val = vfprintf(fp[device], format, args);
		fflush(fp[device]);
		return val;
	#else
		return 0;
	#endif
}

inline int debug::Println::operator ()(const char* format, ...)
{
	#ifdef DEBUG
		va_list args;
		va_start(args, format);
		int val = vfprintf(fp[device], format, args);
		fprintf(fp[device], "\n");
		fflush(fp[device]);
		return val;
	#else
		return 0;
	#endif
}

template <typename T>
inline void debug::Display::operator ()(const T& src, const int len)
{
	#ifdef DEBUG
		memdispex(fp[device], (char*)&src, sizeof(src), len);
	#endif
}

template <typename T>
inline void debug::DisplayFixed::operator ()(const T& src)
{
	#ifdef DEBUG
		memdispex(fp[device], (char*)&src, sizeof(src), sizeof(src));
	#endif
}

template <typename T>
inline void debug::DisplayAddr::operator ()(const T& src, const int len)
{
	#ifdef DEBUG
		memdispex(fp[device], (char*)src, 0, len);
	#endif
}

inline int debug::Timer::halt()
{
	int val = stop();
	#ifdef DEBUG
		println("Time: %dms", val);
	#endif
	return val;
}

自用debug单元的更多相关文章

  1. delphi一些小技巧 从别处看到

    开发环境--------    Delphi 7是一个很经典的版本,在Win2000/XP下推荐安装Delphi 7来开发软件,在Vista下推荐使用Delphi 2007开发软件.安装好Delphi ...

  2. (转载)Delphi开发经验谈

    Delphi开发经验谈 开发环境-------- Delphi 7是一个很经典的版本,在Win2000/XP下推荐安装Delphi 7来开发软件,在Vista下推荐使用Delphi 2007开发软件. ...

  3. jmeter sampler maven项目排错记

    eclipse 创建的maven项目,引入jar包之后出现红色叹号,一直找不到原因,连main方法都无法运行,提示找不到类: 错误: 找不到或无法加载主类 soapsampler.SoapSample ...

  4. c++debug&注意事项 自用 持续更新

    cin后回车程序直接退出: 加system("pause");在return 0;前面 C++ 控制cout输出的小数位数 C++中的cout.setf().cout.precis ...

  5. jquery操作表格 合并单元格

    jquery操作table,合并单元格,合并相同的行 合并的方法 $("#tableid").mergeCell({ cols:[X,X] ///参数为要合并的列}) /** * ...

  6. 汇编语言基础 debug的使用

    -r 查看,改变CPU寄存器的内容 -r 加上寄存器名 在:后输入要写入的数据后 完成更改 debug 随着CS IP的改变 对应的汇编指令也不同 -r ip -r cs修改 ip cs 的值 d 段 ...

  7. debug命令简介

    debug命令不区分大小,debug的命令都是一个字母,后跟或不跟参数 1.debug [路径\文件] [参数] [参数]--[参数] debug相应程序 2. D(Dump) [地址] [范围] 显 ...

  8. Eclipse Debug

    [IT168 专稿]调试的方法虽然千千万万,但归根结底,就是找到引发错误的代码.Eclipse调试器的目标是让程序员能对本地或远程程序进行错误侦测与诊断.该调试器提供所有标准调试功能,包括进行单步执行 ...

  9. 汇编基础知识之二debug的使用

    DEBUG的使用 (要在win32位习题下进行,win7 64位需要安装DosBox和debug这2个软件): 1:win64位下debug的使用教程: 下载debug.exe,这里我把debug放在 ...

随机推荐

  1. Oauth2.0

    注:Access token 为第三方平台的token,在用户授权时使用Refresh Token为用户的token get/post参数时,一般采用字典排序

  2. 尚学堂Spring视频教程(二):Spring控制反转

    用Spring来实现IOC 在上节中我们自定义了一个接口BeanFactory和类ClassPathXmlApplicationContext来模拟Spring,其实它们在Spring中确实是存在的, ...

  3. oracleclient连oracle库 报System.Data.OracleClient 需要 Oracle 客户端软件 8.1.7 或更高版本

    在iis下发布eworkflow+eform+ebiao的代码,访问oracle的数据库,用oracleClient或者oledb的方式连接,有时会报“System.Data.OracleClient ...

  4. iPhone与iPad在开发上的区别

    *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...

  5. Android学习起步 - 新建工程及相关

    新手起步迷迷糊糊,以下记录迷惑之处,大家共勉!!! 1.创建安卓应用工程 选择Andriod Application Project 点下一步直到完成. 二.下面是新建工程注意的地方 (1)首选删除系 ...

  6. 牛客网程序员面试金典:1.1确定字符互异(java实现)

    问题描述: 请实现一个算法,确定一个字符串的所有字符是否全都不同.这里我们要求不允许使用额外的存储结构. 给定一个string iniString,请返回一个bool值,True代表所有字符全都不同, ...

  7. messagePaneHost

    Microsoft.Dynamics.Framework.UI.WinForms.Controls.MessageBarType messageBarType; super(); imageList ...

  8. ScrollView左右约束的坑

    问题:因为要适配iPad,有些页面拉伸会很难看,需要适配成下图样子,但是按照比例调整了ScrollView左右间距之后出现左右可以滑动,设置contentSize的X为0 不起作用,   之后多番尝试 ...

  9. js的事件的绑定

    js的绑定事件 绑定事件有什么用,当你一个按钮点击时需要执行2个函数,就可以用绑定事件,一般只有没绑定事件增加两个onclick函数,第二会覆盖第一个函数的. <!DOCTYPE html> ...

  10. Linux系统启动级别及顺序

    Linux系统有7个运行级别(runlevel)运行级别0:系统停机状态,系统默认运行级别不能设为0,否则不能正常启动运行级别1:单用户工作状态,root权限,用于系统维护,禁止远程登陆运行级别2:多 ...