如何使用istream_iterator将无符号字符向量转换为字符串?

How could I use istream_iterator to convert unsigned char vector to a string?

本文关键字:转换 向量 字符串 字符 无符号 istream 何使用 iterator      更新时间:2023-10-16

我可以用普通的循环来做到这一点:

vector<unsigned char> v{3, 13, 23, 83};
stringstream ss;
for (auto &el : v)
ss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(el);
cout << ss.str() << endl;

我正在寻找允许我使用 std::copy 的方法:

std::copy(
std::begin(v),
std::end(v),
std::ostream_iterator<int>(ss << std::hex << std::setw(2) << std::setfill('0'))
);

它没有给我与 for 循环方法相同的输出值。 我对此有两个问题:

  1. 我怎样才能让它工作,以便 std::copy 方法提供与 for 循环方法相同的输出值和格式?
  2. 这两种方法在理论上哪个更好?

您使用 std::copy 的方法与

ss << std::hex << std::setw(2) << std::setfill('0');
std::copy(
std::begin(v),
std::end(v),
std::ostream_iterator<int>(ss)
);

std::setw 设置的宽度在第一次输出操作后消失,因此只有第一个字符的输出才会有它。

要使用 std::copy,您必须编写一个自定义迭代器,而不是使用 std::ostream_iterator。

您的第一种方法更好,因为它更短且更容易理解。

为了使用标准算法和输出迭代器,我们可以定义一个新类并重载流插入运算符<<。运算符<<std::copy为我们要流式传输的每个项目调用。

template <class T>
class HexOut
{
public:
HexOut(T val) : value(val)
{
}
friend std::ostream& operator<<(std::ostream& os, const HexOut<T>& elem)
{
os << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(elem.value) << std::dec;
return os;
}
private:
T value;
};
int main()
{
std::vector<unsigned char> v{ 3, 13, 23, 83 };
std::copy(v.begin(), v.end(), std::ostream_iterator<HexOut<unsigned char>>(std::cout));
return 0;
}

在这里,运算符<<每次都设置正确的输出标志,并将无符号字符转换为整数。如您所见,我们必须编写更多代码并定义一个新类。对于这样的简单任务来说,这可能是矫枉过正。但是,使用迭代器可以跨不同类型的流移植,我们利用了许多算法函数,例如std:copy.另外,所有格式都包含在运算符<<中,这使得它更易于维护。