随笔-89  评论-224  文章-23  trackbacks-0
   最近在项目中调试串口,,总结封装了字符串转化为16进制显示的算法,串口数据发送一般为ASCII和16进制两种,当收到数据时数据也有ASCII和16进制显示两种方式,下面给出一种转化算法,该算法基于字符类型参数化的模板实现,字符串的转化只是调用其内存版本,算法原理是对字符串内存进行操作转化,以一个字节(unsigned char类型)为单位,分别取其高4位和低4位(范围为0x0--0xF), 转化为对应的目标字符('0'--'F')显示,代码如下
 1/**
 2    @brief MemToHex  
 3    @param template charT 字符类型
 4    @param src  源缓冲区
 5    @param size  lpSrc指向数据的大小,字节数
 6    @param tag  显示分隔符,默认为0表示空字符
 7    @return       返回转化后16进制字符串
 8*/

 9template<typename charT>
10inline std::basic_string<charT> MemToHex(const void* src, size_t size, bool upper = true,charT tag = 0)
11{
12    std::basic_string<charT> strDest;
13    strDest.reserve(2*size);
14    
15    unsigned char* pSrc = (unsigned char*)src;
16    unsigned char  buf[2];
17
18    for (size_t i = 0; i < size; ++i)
19    {
20        unsigned char c0 = *pSrc >> 4;  
21        if ( c0 >= 0x0 && c0 <= 0x9)
22            buf[0= c0 - 0 + '0';
23        else 
24            buf[0= c0 - 10 + (upper ? 'A' : 'a');
25        
26        unsigned char c1 = *pSrc++ & 0x0F;
27        if ( c1 >= 0x0 && c1 <= 0x9)
28            buf[1= c1 - 0 + '0';
29        else 
30            buf[1= c1 - 10 + (upper ? 'A' : 'a');
31        
32        strDest += (charT)buf[0];
33        strDest += (charT)buf[1];
34        if (tag != 0)  strDest += tag;
35    }

36    return strDest;
37}

38
39/**
40    @brief StrToHex 
41    @param template d_charT 目标字符类型
42    @param template s_charT 源字符类型
43    @param src  源字符串
44    @param upper  true表示大写,false表示小写
45    @param tag  显示分隔符,默认为0表示空字符
46    @return       返回转化后16进制字符串
47*/

48template<typename d_charT,typename s_charT>
49inline std::basic_string<d_charT> StrToHex(const s_charT* src, bool upper = true,d_charT tag = 0)
50{
51    return MemToHex(src,select_variable<is_ansi_char<s_charT>::value>(strlen,wcslen)(src)*sizeof(s_charT),upper,tag);
52}
   在应用中需要转化时, 只需调用StrToHex函数,示例如下:  
1    string strDest1 = StrToHex<char>("123456789汉字ABCXYZ");
2    wstring wstrDest1 = StrToHex<wchar_t>("123456789汉字ABCXYZ",true,' ');
3    string strDest2 = StrToHex<char>(L"123456789汉字ABCXYZ");
4    wstring wstrDest2 = StrToHex<wchar_t>(L"123456789汉字ABCXYZ"true,L',');
5
6    TRACE4("%s \n", strDest1.c_str());
7    TRACE4(L"%s \n", wstrDest1.c_str());
8    TRACE4("%s \n", strDest2.c_str());
9    TRACE4(L"%s \n", wstrDest2.c_str());
   结果输出如下:
1313233343536373839BABAD7D641424358595A 
231 32 33 34 35 36 37 38 39 BA BA D7 D6 41 42 43 58 59 5A  
3310032003300340035003600370038003900496C575B410042004300580059005A00 
431,00,32,00,33,00,34,00,35,00,36,00,37,00,38,00,39,00,49,6C,57,5B,41,00,42,00,43,00,58,00,59,00,5A,00
posted on 2009-06-27 13:08 春秋十二月 阅读(11461) 评论(6)  编辑 收藏 引用 所属分类: Algorithm

评论:
# re: 一种字符串转化为16进制显示的算法 2009-06-27 20:21 | nono
char *_itoa(
int value,
char *str,
int radix
);
char *_i64toa(
__int64 value,
char *str,
int radix
);
char * _ui64toa(
unsigned _int64 value,
char *str,
int radix
);
wchar_t * _itow(
int value,
wchar_t *str,
int radix
);
wchar_t * _i64tow(
__int64 value,
wchar_t *str,
int radix
);
wchar_t * _ui64tow(
unsigned __int64 value,
wchar_t *str,
int radix
);
template <size_t size>
char *_itoa(
int value,
char (&str)[size],
int radix
); // C++ only
template <size_t size>
char *_i64toa(
__int64 value,
char (&str)[size],
int radix
); // C++ only
template <size_t size>
char * _ui64toa(
unsigned _int64 value,
char (&str)[size],
int radix
); // C++ only
template <size_t size>
wchar_t * _itow(
int value,
wchar_t (&str)[size],
int radix
); // C++ only
template <size_t size>
wchar_t * _i64tow(
__int64 value,
wchar_t (&str)[size],
int radix
); // C++ only
template <size_t size>
wchar_t * _ui64tow(
unsigned __int64 value,
wchar_t (&str)[size],
int radix
); // C++ only
  回复  更多评论
  
# re: 一种字符串转化为16进制显示的算法 2009-06-28 17:54 | qinqing1984
我知道你的意思,buf为2个字节时库转化函数发生栈异常,buf改为3个字节时就正常了,为了节省一个字节,因此自己写了转化算法
@nono
  回复  更多评论
  
# re: 一种字符串转化为16进制显示的算法 2010-03-03 16:12 | mubai
上面那个字符串转ASCII码的小程序写得非常好,但是如果要从你的程序生成的最终ASCII码再还原回原来的字符串需要怎么做呢?您能给我点帮助吗?  回复  更多评论
  
# re: 一种字符串转化为16进制显示的算法 2011-06-06 19:28 | Rn
用来转换车牌可以么?
车牌里头有汉字  回复  更多评论
  
# re: 一种字符串转化为16进制显示的算法 2011-07-06 09:01 | can
很好 非常感谢  回复  更多评论
  
# re: 字符串16进制显示 2012-04-26 18:08 | shoscky
您好,这个程序好像不能处理内存里有00的情况  回复  更多评论
  

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理