在这个帖子中,有人评论说下面的代码只能在'玩具'项目中使用.不幸的是,他还没有回来说明为什么它不符合生产质量,所以我希望社区中的某个人能够向我保证代码没问题(因为我非常喜欢)或者找出错误.
template< class T1, class T2> void hexascii( T1& out, const T2& in ) { out.resize( in.size() * 2 ); const char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7','8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; T1::iterator outit = out.begin(); for( T2::const_iterator it = in.begin(); it != in.end(); ++it ) { *outit++ = hexDigits[*it >> 4]; *outit++ = hexDigits[*it & 0xF]; } } templatevoid asciihex( T1& out, const T2& in ) { size_t size = in.size; assert( !(size % 2) ); out.resize( size / 2 ); T1::iterator outit = out.begin(); for( T2::const_iterator it = in.begin(); it != in.end(); it += 2, ++outit ) { *outit = ((( (*it > '9' ? *it - 0x07 : *it) - 0x30) << 4) & 0x00f0) + (((*(it+1) > '9' ? *(it+1) - 0x07 : *(it+1)) - 0x30) & 0x000f); } }
编辑:感谢您的帮助,您已经做了一些重大改进.我从你的答案中写出了两种建议风格的函数.一些粗略的测试表明第二种方法比第一种方法稍微快一些,但IMO比第一种方法的可读性提高了.
templatevoid asciihex2( T1& out, const std::string& in ) { dassert( sizeof(T1::value_type)==1 ); size_t size = in.size(); assert( !(size % 2) ); out.resize( size / 2 ); T1::iterator outit = out.begin(); for( size_t i = 0; i < in.size(); i += 2 ) { int tmp; sscanf( in.c_str() + i, "%02X", &tmp ); *outit++ = tmp; } } template void asciihex3( T1& out, const std::string& in ) { dassert( sizeof(T1::value_type)==1 ); size_t size = in.size(); assert( !(size % 2) ); out.resize( size / 2 ); T1::iterator outit = out.begin(); const char hexDigits[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}; for( std::string::const_iterator it = in.begin(); it != in.end(); it += 2, ++outit ) { *outit = (hexDigits[(*it - 0x30) & 0x1f] << 4) + hexDigits[((*(it+1) - 0x30) & 0x1f)]; } }
这段代码中的一些假设:1:它们不是通用的,而是在匿名名称空间中用于转换特定类的数据.2:模板是必需的,因为正在使用两个单独的容器类型(一个是std :: vector,另一个是来自第三方库的类似字节数组类型容器.3:目的是能够转换不确定的二进制数据长度为字符串然后再返回(0x1234abcd < - >"1234abcd")4:在调试和释放模式下断言陷阱错误5:当调用这些函数时,字符串的大小已经被检查,断言用于如果出现严重问题则终止处理6:需要一些评论
任何其他想法赞赏.
考虑到在标准C scanf和printf函数中有直接的十六进制转换,似乎很多模板化代码实现得很少.何必?
我对它的主要评论是,它很难阅读.
特别:
*outit = ((( (*it > '9' ? *it - 0x07 : *it) - 0x30) << 4) & 0x00f0) + (((*(it+1) > '9' ? *(it+1) - 0x07 : *(it+1)) - 0x30) & 0x000f)
如果我继承了代码,那么我的大脑会花一点时间来解决这个问题,并让我烦恼.