Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将二进制数据转换为可打印十六进制_C++_Templates_Stl - Fatal编程技术网

C++ 将二进制数据转换为可打印十六进制

C++ 将二进制数据转换为可打印十六进制,c++,templates,stl,C++,Templates,Stl,在线程中,有人评论说,以下代码应该只用于“玩具”项目。不幸的是,他没有回来解释为什么它不符合生产质量,所以我希望社区中的一些人能够向我保证代码是正确的(因为我非常喜欢),或者找出错误所在 template< class T1, class T2> void hexascii( T1& out, const T2& in ) { out.resize( in.size() * 2 ); const char hexDigits[] = {'0', '1'

在线程中,有人评论说,以下代码应该只用于“玩具”项目。不幸的是,他没有回来解释为什么它不符合生产质量,所以我希望社区中的一些人能够向我保证代码是正确的(因为我非常喜欢),或者找出错误所在

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];
    }
}

template<class T1, class T2>
void 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);
    }
}
模板
空心六面体(T1和out,常数T2和in)
{
out.resize(in.size()*2);
常量字符六位数字[]={0',1',2',3',4',5',6',7',8',9',A',B',C',D',E',F'};
T1::迭代器outit=out.begin();
for(T2::const_迭代器it=in.begin();it!=in.end();++it)
{
*outit++=hexDigits[*it>>4];
*outit++=hexDigits[*it&0xF];
}
}
样板
无效asciihex(T1和out,常数T2和in)
{
尺寸=英寸尺寸;
断言(!(大小%2));
out.调整大小(大小/2);
T1::迭代器outit=out.begin();
for(T2::const_迭代器it=in.begin();it!=in.end();it+=2,++outit)
{
*outit=(((*it>'9'?*it-0x07:*it)-0x30)'9'?*(it+1)-0x07:*(it+1))-0x30和0x000f);
}
}
编辑:谢谢你们的帮助,你们已经取得了很大的进步。我已经根据你的答案用两种建议的风格编写了函数。一些粗略的测试表明,第二种方法的速度略快于第一种方法,但在我看来,第一种方法的可读性有所提高,这远远超过了第二种方法

template<class T1>
void 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<class T1>
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)];
    }
}
模板
无效asciihex2(T1和out,常量标准::字符串和in)
{
dassert(sizeof(T1::value_type)==1);
大小=英寸大小();
断言(!(大小%2));
out.调整大小(大小/2);
T1::迭代器outit=out.begin();
对于(大小i=0;i*outit=(十六进制数字[(*it-0x30)和0x1f]如果在标准Cscanfprintf函数中有直接的十六进制转换,那么似乎有很多模板代码实现的很少。为什么要麻烦呢?

如果在标准Cscanf函数中有直接的十六进制转换,那么似乎有很多模板代码实现的很少rong>printf函数。为什么要麻烦呢?

我的主要意见是它很难阅读

特别是:

*outit = ((( (*it > '9' ? *it - 0x07 : *it)  - 0x30) << 4) & 0x00f0) + 
            (((*(it+1) > '9' ? *(it+1) - 0x07 : *(it+1)) - 0x30) & 0x000f)
*outit=(((*it>'9'?*it-0x07:*it)-0x30)'9'?*(it+1)-0x07:*(it+1))-0x30和0x000f)

我的大脑需要一点时间来摸索,如果我继承了代码,我会很恼火。

我的主要评论是它很难阅读

特别是:

*outit = ((( (*it > '9' ? *it - 0x07 : *it)  - 0x30) << 4) & 0x00f0) + 
            (((*(it+1) > '9' ? *(it+1) - 0x07 : *(it+1)) - 0x30) & 0x000f)
*outit=(((*it>'9'?*it-0x07:*it)-0x30)'9'?*(it+1)-0x07:*(it+1))-0x30和0x000f)

我的大脑需要一点时间来摸索,如果我继承了代码,我会很恼火。

我并不反对它。它是通用的(在限制范围内),在需要的地方使用常量、引用等。它缺少一些文档,而且
asciihex
*outit
的分配乍一看不太清楚

resize
初始化不必要的输出元素(改用
reserve

也许泛型有点太灵活了:你可以用你喜欢的任何数据类型为算法提供数据,而你应该只给它十六进制数(而不是一个
向量
双精度
s)


事实上,它可能是一个很好的库函数。我并不反对它。它是通用的(在限制范围内),在需要时使用常量、引用等。它缺少一些文档,而且
asciihex
*outit
赋值乍一看也不太清楚

resize
初始化不必要的输出元素(改用
reserve

也许泛型有点太灵活了:你可以用你喜欢的任何数据类型为算法提供数据,而你应该只给它十六进制数(而不是一个
向量
双精度
s)


事实上,考虑到存在良好的库函数,它可能是一个函数。

它应该做什么?hexascii或asciihex没有众所周知的公认含义,因此名称应该更改

[编辑]
从二进制到十六进制表示法的转换通常不应称为ascii…,因为ascii是一种7位格式。

它应该做什么?hexascii或asciihex没有众所周知的公认含义,因此名称应该更改

[编辑]
从二进制到十六进制的转换通常不应称为ascii…,因为ascii是一种7位格式。

我看到一些问题:

如果它仅用于存储8位类型(例如,char或unsigned char)的输入容器,则此操作非常有效。例如,如果与右移后的值大于15的32位类型一起使用,则以下代码将失败。建议始终使用掩码以确保查找索引始终在范围内

*outit++ = hexDigits[*it >> 4];
如果传入一个包含无符号long的容器,那么预期的行为是什么?要使它成为一个泛型类,它可能还能够处理32位数字到hext字符串的转换

这仅在输入为容器时有效-如果我只想转换单个字节怎么办?这里的建议是将代码重构为一个核心函数,该函数可以转换单个字节(十六进制=>ascii和ascii=>hex),然后提供其他要使用的函数
*outit = hexDigits[*it]