ifstream seekg有什么问题?

25
我尝试使用查找和重新读取数据的方式,但代码失败了。
代码如下:
std::ifstream ifs (filename.c_str(), std::ifstream::in | std::ifstream::binary);

std::streampos pos = ifs.tellg();

std::cout <<" Current pos:  " << pos << std::endl;

// read the string
std::string str;
ifs >> str;

std::cout << "str: " << str << std::endl;
std::cout <<" Current pos:  " <<ifs.tellg() << std::endl;

// seek to the old position
ifs.seekg(pos);

std::cout <<" Current pos:  " <<ifs.tellg() << std::endl;

// re-read the string
std::string str2;
ifs >> str2;

std::cout << "str2: (" << str2.size() << ") " <<  str2 << std::endl;
std::cout <<" Current pos:  " <<ifs.tellg() << std::endl;

我的输入测试文件是

qwe

输出结果为

 Current pos:  0
str: qwe
 Current pos:  3
 Current pos:  0
str2: (0)
 Current pos:  -1

有人能告诉我是什么问题吗?


可能是[seekg()函数失效]的重复问题。(http://stackoverflow.com/questions/11264764/seekg-function-fails) - amo
2个回答

41

ifs >> str;因为到达文件结尾而结束时,它会设置eofbit。

在C++11之前,seekg()不能从流的末尾进行定位(注意:你的实际上确实这样做了,因为输出是Current pos: 0,但这并不完全符合要求:它应该不能进行定位或者清除eofbit并进行定位)。

无论哪种方式,为了解决这个问题,您可以在ifs.seekg(pos);之前执行ifs.clear();


2
尽管C++标准(n3337 §27.7.2.3.41)表示“效果:表现为未格式化的输入函数(如27.7.2.3第1段所述),除了该函数首先清除eofbit...”,但实际上我们仍然需要手动调用clear(),这非常奇怪。 - Gavin
1
@Gavin 我也观察到了类似的行为。然而,事实证明,当使用read读取文件的字节数时,没有设置eof位。并且只有在您请求比文件包含的字节数多一个字节时,才会设置failbit和eofbit,但是自C++11以来,只有eofbit会被seekg清除。 - mxmlnkn

6

看起来在读取字符时,它遇到了EOF并将其标记为流状态。当调用seekg()时,流状态不会改变,因此下一次读取检测到EOF位已设置并返回而不进行读取。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接