C++将一个数值转化为二进制字符串

原文链接:https://my.oschina.net/u/160145/blog/264391

问题:如何将一个数值如0xfaceabcd转化成二进制的字符串?

第一时间想到的是STL

对了就是bitset对象
详细见http://www.cplusplus.com/reference/bitset/bitset/?kw=bitset

#include <iostream>
#include <bitset>
using namespace std;
int main()
{
	bitset<32> t(0xfaceabcd);
	cout<<"0x"<<hex<<t.to_ulong()<<"="<<t.to_string()<<"b"<<endl;
}
输出:0xfaceabcd=11111010110011101010101111001101b

如果是在windows下要实现,ANSI下bitset是正常
但是UNICODE版
使用bitset对象就显得力不从心
咋办?咋办?咋办?
不如自己定义一个模板类来得快

#include <windows.h>
#include <tchar.h>
template <typename T>  
class XBIT
{
private:
	UINT 	m_size;//位数
	T 	m_value;//值
	TCHAR 	*m_szBuf;//二进制字符串,用new动态创建,destroy()中消除
public:
	XBIT(T value=0)
	{
		m_size=sizeof(T)*8;
		m_value=value;
		m_szBuf=new TCHAR[m_size+1];//+1 for NULL terminal
		to_string();
	}
	~XBIT()
	{
		destroy();
	}
	void destroy()
	{
		if( NULL!=m_szBuf )
		{
			delete[] m_szBuf;
			m_szBuf=NULL;
		}
	}
	T getvalue()
	{
		return m_value;
	}
	void setvalue(T value)
	{
		m_value=value;
		to_string();
	}
	TCHAR *getstr()
	{
		return m_szBuf;
	}
	TCHAR *to_string() 
	{
		memset(m_szBuf,'x',m_size+1);
		m_szBuf[m_size]=TEXT('\0');
		for(int n=m_size-1;n>=0;n--)//方法一
		{		
			TCHAR ch=(m_value>>n)&0x1 ?TEXT('1'):TEXT('0');
			m_szBuf[m_size-1-n]=ch;
		}
		//for(int n=0;n<m_size;n++)//方法二
		//{
		//TCHAR ch=( m_value>>(m_size-1-n) )&0x1 ?TEXT('1'):TEXT('0');
		//m_szBuf[n]=ch;	
		//printf("[d%02d]=%c\t",n,ch); 
		//}
		return m_szBuf;
	}	

};

下面是测试

int _tmain()
{
 	XBIT<long> f(0xfaceabcd);
	_tprintf(_T("0x%x=%sb"),f.getvalue(),f.to_string());
}
结果
0xfaceabcd=11111010110011101010101111001101b
然后我们在代码最前面加入
#ifndef UNICODE
#define UNICODE
#endif
#ifndef _UNICODE
#define _UNICODE
#endif
测试UNICODE成功

改进版本
#ifndef UNICODE
#define UNICODE
#endif
#ifndef _UNICODE
#define _UNICODE
#endif

#include <windows.h>
#include <tchar.h>
	
template <typename T>  
class XBIT
{
private:
	UINT 	m_size;//位数
	T 		m_value;//值
	TCHAR 	*m_szBuf;//二进制字符串,用new动态创建,destroy()中消除
public:
	XBIT(T value=0)
	{
		m_size=sizeof(T)*8;
		m_value=value;
		m_szBuf=new TCHAR[m_size+1];//+1 for NULL terminal
		to_string();
	}
	~XBIT()
	{
		destroy();
	}
	T getvalue()
	{
		return m_value;
	}
	void setvalue(T value)//每次改变均调用私有参数to_string()
	{
		m_value=value;
		to_string();
	}
	TCHAR *getstring()
	{
		return m_szBuf;
	}
private:	
	void destroy()
	{
		if( NULL!=m_szBuf )
		{
			delete[] m_szBuf;
			m_szBuf=NULL;
		}
	}
	TCHAR *to_string() 
	{
		memset(m_szBuf,0,m_size+1);
		m_szBuf[m_size]=TEXT('\0');
		for(int n=m_size-1;n>=0;n--)//方法一
		{		
			TCHAR ch=(m_value>>n)&0x1 ?TEXT('1'):TEXT('0');
			m_szBuf[m_size-1-n]=ch;
		}
		//for(int n=0;n<m_size;n++)//方法二
		//{
		//TCHAR ch=( m_value>>(m_size-1-n) )&0x1 ?TEXT('1'):TEXT('0');
		//m_szBuf[n]=ch;	
		//printf("[d%02d]=%c\t",n,ch); 
		//}
		return m_szBuf;
	}	

};

int _tmain()
{
 	XBIT<unsigned long long> f(0xabcdef0123456789);
	_tprintf(_T("0x%x=%sb"),f.getvalue(),f.getstring());
}


然后弹出错误窗口

C++将一个数值转化为二进制字符串

哪里错了?
tt.exe 中的 0x00402532 处未处理的异常: 0xC0000005: 读取位置 0xabcdef01 时发生访问冲突

原来是这个_tprintf(_T("0x%x=%sb"),f.getvalue(),f.getstring());

看到了吗
sizeof(unsigned long long) =8字节
原来%x格式化输出也不是万能的,我们要把 %x 改成 %I64x,或者 %llx


 _tprintf(_T("0x%I64x=%sb"),f.getvalue(),f.getstring());
或 
_tprintf(_T("0x%llx=%sb"),f.getvalue(),f.getstring());
输出正常
0xabcdef0123456789=1010101111001101111011110000000100100011010001010110011110001001b

转载于:https://my.oschina.net/u/160145/blog/264391

上一篇:squid ACL控制列表,缓存


下一篇:以追加的方式以二进制写入