c++ - Ostream tellp 在 Windows 上失败但在 Linux 上没有

标签 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->seekg(oldPos) 中,但是因为状态在 myIstream 和 myOstream 之间共享,所以直到调用 ostream 时才会捕获错误。字符串缓冲区是延迟分配的,但 seekp() 不适应这一点。解决此问题的方法是用垃圾数据填充字符串流,或者更好的方法是在使用之前检查它是否为空。

最佳答案

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

关于c++ - Ostream tellp 在 Windows 上失败但在 Linux 上没有,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40986375/

相关文章:

c++ - 当方法抛出异常时,方法范围内的对象会被销毁吗?

python - 外语python中的Windows CMD行错误

linux - TFS 2015 Linux 构建代理配置抛出 401 错误

linux - 在 Linux fork 期间防止文件描述符继承

c++ - 以编程方式检测 VMWare

windows - 为什么不能在 cmd.exe 可执行文件的选项周围加上引号?

c++ - 将可变迭代器参数转换为值类型的元组

C++11 lambda - 为什么我需要捕获自动持续时间变量?

.net - 如何在.net项目中使用C++类库

java - Java中将文本文件读入列表