【问题标题】:How could I use istream_iterator to convert unsigned char vector to a string?如何使用 istream_iterator 将 unsigned char 向量转换为字符串?
【发布时间】:2019-12-27 05:38:53
【问题描述】:

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

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 的输出与 for 循环方法相同
  • 我再重复一遍:正确的输出是什么,它与错误的输出有何不同?
  • 很明显,第一个结果是030d1753,第二个结果是03d1753

标签: c++ casting iterator format copy


【解决方案1】:

您使用 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。

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

【讨论】:

    【解决方案2】:

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

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

    这里操作符&lt;&lt; 每次都设置正确的输出标志,并将 unsigned char 转换为 int。如您所见,我们必须编写更多代码并定义一个新类。对于像这样的简单任务,这可能是矫枉过正。但是,使用迭代器使其可跨不同类型的流进行移植,并且我们利用了许多算法函数,例如std:copy。此外,所有格式都包含在运算符 &lt;&lt; 中,这使其更易于维护。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-18
      • 2018-03-27
      • 1970-01-01
      • 2022-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多