如何从stringstream转换为unsigned char向量,反之亦然?

时间:2018-12-15 21:47:46

标签: c++ serialization stdvector stringstream c++-standard-library

我有@PostContstruct void initCache() { proxyRefToThisBean.findAllByCategoryId(cat1); proxyRefToThisBean.findAllByCategoryId(cat2); ... } ,其中包含要放入std::stringstream ss;的二进制数据。然后,我要使用std::vector<unsigned char> my_vector;并用它来创建一个与my_vector相同的新std::stringstream new_ss

我尝试做类似此问题的答案的

Is there a more efficient way to set a std::vector from a stream?

和这个问题:

C++: vector to stringstream

最后是:

ss

然后:

std::copy(std::istream_iterator<unsigned char>(ss),
          std::istream_iterator<unsigned char>(),
          std::back_inserter(my_vector));

但是std::copy(my_vector.begin(), my_vector.end(), std::ostream_iterator<unsigned char>(new_ss)); ss不同。我怀疑问题可能与忽略的空白有关,因此我尝试以这种方式制作矢量:

new_ss

但这不能解决问题。

对于可能出什么问题的任何想法或提出解决此问题的更好方法的建议,将不胜感激。

3 个答案:

答案 0 :(得分:1)

使用std::istream_iterator<T>迭代器或std::ostream_iterator<T>势必不起作用(如果输入的话),只是不必要的缓慢(如果输出的话)。问题是std::istream_iterator<T>跳过了前导空格,并且两个迭代器都在格式化的界面上乱七八糟,这使得进行各种检查并没有真正的帮助。

您可以使用std::istreambuf_iterator<char>std::ostreambuf_iterator<char>。我认为通过字符串接口进行转换更有效。

答案 1 :(得分:1)

std::vector具有一个重载构造函数,该构造函数带有一对输入迭代器,这些输入迭代器定义了新向量的内容序列。

std::stringstream ss;

// Fill in your stringstream, then:

std::vector<unsigned char> my_vector{
    std::istreambuf_iterator<char>{ss},
    std::istreambuf_iterator<char>{}
};

答案 2 :(得分:1)

我怀疑这将是一种相当有效的方法:

std::string const test_data = "hello world";

std::stringstream ss(test_data);

// discover size of data in stringstream
auto bof = ss.tellg();
ss.seekg(0, std::ios::end);
auto stream_size = std::size_t(ss.tellg() - bof);
ss.seekg(0, std::ios::beg);

// make your vector long enough
std::vector<unsigned char> v(stream_size);

// read directly in
ss.read((char*)v.data(), std::streamsize(v.size()));

// Now put it into a new stream object
std::stringstream new_ss;

// direct write again
new_ss.write((char const*)v.data(), std::streamsize(v.size()));

// check the result is the same as the original data
assert(new_ss.str() == test_data);

这些可以包装成函数以使其更容易:

std::vector<unsigned char> to_vector(std::stringstream& ss)
{
    // discover size of data in stream
    ss.seekg(0, std::ios::beg);
    auto bof = ss.tellg();
    ss.seekg(0, std::ios::end);
    auto stream_size = std::size_t(ss.tellg() - bof);
    ss.seekg(0, std::ios::beg);

    // make your vector long enough
    std::vector<unsigned char> v(stream_size);

    // read directly in
    ss.read((char*)v.data(), std::streamsize(v.size()));

    return v;
}

std::stringstream to_stream(std::vector<unsigned char> const& v)
{
    std::stringstream ss;
    ss.write((char const*)v.data(), std::streamsize(v.size()));
    return ss;
}

int main()
{
    std::string const test_data = "hello world";

    std::stringstream ss(test_data);

    auto v = to_vector(ss);

    auto new_ss = to_stream(v);

    assert(new_ss.str() == test_data);
}