basic_stringbuf :: in_avail()和basic_stringbuf :: str()的可靠性如何?

时间:2010-08-31 15:36:54

标签: c++ stl iostream

我需要从流中获取所有内容,而不是实际提取它们(就像stringstream::str())。我尝试了basic_stringbuf::str(),但是当流为空时它的行为不正确。为了避免这种情况,我去了basic_stringbuf::in_avail(),但这也没有很好。

在以下测试用例中,in_avail()不会返回流上可用元素的数量,而str()会返回更多元素,而不是当前的元素: / p>

#include <iostream>
#include <iterator>
#include <vector>
#include <sstream>

// extracts everything from the stream
std::vector<unsigned char> stream2vector(std::basic_istream<unsigned char>& stream)
{
    std::vector<unsigned char> retreivedData;
    std::istreambuf_iterator<unsigned char> it(stream);
    const std::istreambuf_iterator<unsigned char> endOfStream;
    retreivedData.insert(retreivedData.begin(), it, endOfStream);
    return retreivedData;
}

int main() {
    std::basic_stringbuf<unsigned char> buf;
    std::basic_iostream<unsigned char> stream(&buf);
    unsigned char array[5] = { 1, 2, 3, 4, 5 };
    stream.write(array, 5);


    std::cout << "rdbuf()->in_avail(): " << buf.in_avail() << "\n";
    std::vector<unsigned char> d1 = stream2vector(stream);
    std::cout << "d1.size(): " << d1.size() << "\n";

    std::cout << "\n";
    // d2 should be empty
    std::vector<unsigned char> d2 = stream2vector(stream);
    std::cout << "d2.size(): " << d2.size() << "\n";
    std::basic_string<unsigned char> s = buf.str();
    std::cout << "buf.str().size(): " << buf.str().size() << "\n";
}

在g ++ 4.4上编译,输出为:

rdbuf()->in_avail(): 1 // expected: 5
d1.size(): 5 // as expected

d2.size(): 0 // as expected
buf.str().size(): 5 // expected: 0

我做错了什么?做我正在尝试的最好的方法是什么?

非常感谢。

1 个答案:

答案 0 :(得分:0)

in_avail是准备从缓冲区读取的字符数,而不是缓冲区本身的大小。这里真的允许返回任何非零值。

然而,我无法回答你所做的最好的方式,因为我不知道你在做什么。如果您已将某些内容作为unsigned char数组,那么您将要执行以下操作:

std::vector<unsigned char> data(array, array + sizeof(array)/sizeof(unsigned char));

如果您只是想将整个流读入一个向量,那么我会完全按照您的要求进行操作;我只是用这个等同的,更简单的一个替换你的stream2vector函数:

// extracts everything from the stream
std::vector<unsigned char> stream2vector(std::basic_istream<unsigned char>& stream)
{
    std::istreambuf_iterator<unsigned char> it(stream);
    const std::istreambuf_iterator<unsigned char> endOfStream;
    return std::vector<unsigned char>(it, endOfStream);
}

我不完全确定为什么你专门针对unsigned char的每个操作 - 我只会使用默认的char版本,因为unsigned char允许相同大小为short,这可能不是你想要的(但我不知道有任何实现这样做)。