将uint8的向量转换为ascii十六进制字符串的更好方法

时间:2014-10-22 08:50:29

标签: c++ vector std

我编写了以下函数,将std::vector uint8_t转换为ascii十六进制string (gnu ++ 98标准)。

 ...
string uint8_vector_to_hex_string(const vector<uint8_t>& v) {
    stringstream ss;
    vector<uint8_t>::const_iterator it;

    for (it = v.begin(); it != v.end(); it++) {
        char hex_char[2];
        sprintf(hex_char, "%x", *it);
        ss << "\\x" << hex_char;
    }

    return ss.str();
}
 ...

工作正常。我想知道是否有更好的方法来进行这种转换,可能不使用stringstream对象和sprintf函数。有什么建议吗?

4 个答案:

答案 0 :(得分:5)

注意:答案是针对标准C ++;对于较旧的方言,可能需要对范围迭代进行微小的修改。我认为这些算法效率的核心问题并不重要。突出问题。)


你可以通过事先知道答案并且不需要做所有这些动态的工作来节省大量的工作。

std::string uint8_vector_to_hex_string(const vector<uint8_t>& v)
{
    std::string result;
    result.reserve(v.size() * 2);   // two digits per character

    static constexpr char hex[] = "0123456789ABCDEF";

    for (uint8_t c : v)
    {
        result.push_back(hex[c / 16]);
        result.push_back(hex[c % 16]);
    }

    return result;
}

本着&#34;识别算法&#34;的精神,这里是一个用于数值序列的位值格式化的分离算法。首先是用例:

#include <iostream>
#include <string>
#include <vector>

// bring your own alphabet
constexpr char Alphabet[] = "0123456789ABCDEF";

// input
std::vector<unsigned char> const v { 31, 214, 63, 9 };

// output (Note: *our* responsibility to make allocations efficient)
std::string out;
out.reserve(v.size() * 2);

// the algorithm
place_value_format<char,     // output type
                      2,     // fixed output width
                     16>(    // place-value number base
    v.begin(), v.end(),      // input range
    std::back_inserter(out), // output iterator
    Alphabet);               // digit representation

现在算法:

#include <algorithm>
#include <iterator>

template <typename Out, std::size_t NDigits, std::size_t Base,
          typename InItr, typename OutItr>
OutItr place_value_format(InItr first, InItr last, OutItr out, Out const * digits)
{
    for (; first != last; ++first)
    {
        Out unit[NDigits];

        auto val = *first;

        for (auto it = std::rbegin(unit); it != std::rend(unit); ++it)
        {
            *it = digits[val % Base];
            val /= Base;
        }

        out = std::copy(std::begin(unit), std::end(unit), out);
    }

    return out;
}

答案 1 :(得分:5)

您可以直接使用stringstream进行十六进制格式化:

...
string uint8_vector_to_hex_string(const vector<uint8_t>& v) {
    stringstream ss;
    ss << std::hex << std::setfill('0');
    vector<uint8_t>::const_iterator it;

    for (it = v.begin(); it != v.end(); it++) {
        ss << "\\x" << std::setw(2) << static_cast<unsigned>(*it);
    }

    return ss.str();
}
...

答案 2 :(得分:0)

如果您不介意在项目中使用Boost,可以使用boost::hex

#include <boost/algorithm/hex.hpp>

std::string uint8_vector_to_hex_string(const std::vector<uint8_t> & v) {
    std::string result;
    result.reserve(v.size() * 2);
    boost::algorithm::hex(v.begin(), v.end(), std::back_inserter(result));
    return result;
}

答案 3 :(得分:0)

我会选择不依赖于其他类的东西:

setTimeout(() => {
  updateSize();
});