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

发布于 2024-09-16 13:09:50 字数 1811 浏览 2 评论 0原文

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

在以下测试用例中,in_avail() 不返回流上可用元素的数量,而 str() 返回更多 个元素比当前存在的内容:

#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

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

多谢。

I need to get all the contents from a stream, without actually extracting them (just like stringstream::str()). I've tried basic_stringbuf::str(), but it behaves incorrectly when the stream is empty. To avoid that case, I had a go at basic_stringbuf::in_avail(), but that hasn't worked out very well either.

In the following test case, in_avail() doesn't return the number of available elements on the stream, and str() returns more elements than what is currently there:

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

Compiling on g++ 4.4, the output is:

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

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

What am I doing wrong? What's the best way to do what I'm trying?

Thanks a lot.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

假装不在乎 2024-09-23 13:09:50

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 具有相同的大小,这可能不是您想要的(但我不是了解执行此操作的任何实现)。

in_avail is the number of characters ready to be read from the buffer, not the size of the buffer itself. It's really allowed to return any nonzero value here.

However, I can't answer what the best way is of what you're doing, because I don't know what you're doing. If you already have things as an unsigned char array, then you're going to want to do:

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

If you're just trying to read a whole stream into a vector, then I would do exactly what you're doing; I'd just replace you're stream2vector function with this, equivalent, simpler one:

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

I'm not entirely sure why you're specializing every operation here for unsigned char -- I would just use the default char versions, because unsigned char is allowed to be the same size as a short, which is probably not what you want (but I am not aware of any implementation that does this).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文