我在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并将其转换为uint64
。 Before Fail
和Bad flag
都返回0. After Fail
标志返回1,Bad flag
返回0.
我读到这是因为哨兵的建设失败了,但我无法弄清楚如何解决这个问题。
编辑:
在使用代码后,我意识到我遗漏了部分代码。我理解的是,为了获得代码大小,我们已经读取了多少,调整指向该位置的指针,然后计算剩余多少并返回该值。但是由于iostream是新的并且它被转换为.get()返回内存位置并传递if语句。然后,istream部分将指针更改为最终结果以及ostream部分失败的原因。这是对的吗?
编辑2: 找到了解决方案。问题出在myIstream-&gt; seekg(oldPos)中,但由于状态在myIstream和myOstream之间共享,因此在ostream调用之前不会捕获错误。字符串缓冲区被延迟分配,但seekp()不适应这种情况。解决这个问题的方法是使用垃圾数据填充字符串流,或者更好地在使用之前检查它是否为空。
答案 0 :(得分:0)
找到解决方案。问题出在myIstream-&gt; seekg(oldPos)中,但由于状态在myIstream和myOstream之间共享,因此在ostream调用之前不会捕获错误。字符串缓冲区被延迟分配,但seekp()不适应这种情况。解决此问题的方法是使用垃圾数据填充字符串流,或者更好地在使用它之前检查它是否为空。 - Namox9001