Ostream tellp在Windows上失败但在Linux上失败

时间:2016-12-06 01:33:31

标签: c++ linux windows ostream

我在Windows 10和Linux中使用Qt 5.7执行相同的代码,它只适用于Linux。 我试图确定我刚刚创建的 Ostream IOstream的大小,所以它应该是空的。在Linux中,Size()返回0,但在Windows中,它返回-1,因为tellp()失败。

    #include "stdafx.h"
    #include <iostream>
    #include <fstream>
    #include <memory>
    #include <sstream>

    class Foo {
private:
    std::shared_ptr<std::ostream> myOstream;
    std::shared_ptr<std::istream> myIstream;

public:
    Foo::Foo(std::shared_ptr<std::iostream> myIostream)
        : myIstream(std::static_pointer_cast<std::istream>(myIostream))
        , myOstream(std::static_pointer_cast<std::ostream>(myIostream))
    {}

    uint64_t Foo::Size() {
        int ret = 0;

        std::cout << "Before – Fail Flag: " << myOstream->fail() << ", Bad Bit: " << myOstream->bad() << std::endl;

        if (myIstream.get() != nullptr) {
            myIstream->clear();
            auto oldPos = myIstream->tellg();            //returns 0
            myIstream->seekg(0, std::ios_base::end);
            ret = static_cast<int>(myIstream->tellg());  //returns 0
            myIstream->seekg(oldPos);
        }

        if (myOstream.get() != nullptr) {
            auto oldPos = myOstream->tellp();           //returns -1
            myOstream->seekp(0, std::ios_base::end);
            ret = static_cast<int>(myOstream->tellp()); //returns -1
            myOstream->seekp(oldPos);
        }
            //Fail Flag returns -1, Bad Bit Flag returns 0
        std::cout << "After – Fail Flag: " << myOstream->fail() << ", Bad Bit: " << myOstream->bad() << std::endl;

        return static_cast<uint64_t>(ret);
    }
};

int main()
{
    auto myStringStream = std::make_shared<std::stringstream>(
        std::ios::in | std::ios::out | std::ios::binary);

    Foo foo(std::static_pointer_cast<std::iostream>(myStringStream));

    std::cout << "Size: " << foo.Size() << std::endl;

    system("pause");
    return 0;
}

我得到18446744073709551615作为大小,因为它返回-1并将其转换为uint64Before FailBad flag都返回0. After Fail标志返回1,Bad flag返回0.

我读到这是因为哨兵的建设失败了,但我无法弄清楚如何解决这个问题。

编辑:

在使用代码后,我意识到我遗漏了部分代码。我理解的是,为了获得代码大小,我们已经读取了多少,调整指向该位置的指针,然后计算剩余多少并返回该值。但是由于iostream是新的并且它被转换为.get()返回内存位置并传递if语句。然后,istream部分将指针更改为最终结果以及ostream部分失败的原因。这是对的吗?

编辑2: 找到了解决方案。问题出在myIstream-&gt; seekg(oldPos)中,但由于状态在myIstream和myOstream之间共享,因此在ostream调用之前不会捕获错误。字符串缓冲区被延迟分配,但seekp()不适应这种情况。解决这个问题的方法是使用垃圾数据填充字符串流,或者更好地在使用之前检查它是否为空。

1 个答案:

答案 0 :(得分:0)

找到解决方案。问题出在myIstream-&gt; seekg(oldPos)中,但由于状态在myIstream和myOstream之间共享,因此在ostream调用之前不会捕获错误。字符串缓冲区被延迟分配,但seekp()不适应这种情况。解决此问题的方法是使用垃圾数据填充字符串流,或者更好地在使用它之前检查它是否为空。 - Namox9001