我正在与ifstream一起玩,以熟悉它。我正在尝试使用seekg来告知文件的位置,但这给了我错误的结果。
这个想法是:
原始文件如下所示(Windows格式):
file.txt
aA
bB
cC
dD
eE
fF
运行我的代码,我得到的结果是:
position: 0
got: a
position: 6
got: A
position: 7
但是,对于此文件:
file.txt
aAbBcCdDeEfF
我得到这些结果
position: 0
got: a
position: 1
got: A
position: 2
这是我使用的代码:
test.cpp (mingw / gcc5.3)
#include <fstream>
#include <iostream>
using namespace std;
static char s[10];
int main(int argc, char **argv)
{
ifstream f("file.txt");
cout << "position: " << f.tellg() << "\n";
f.read(s, 1);
cout << "got: " << s << "\n";
cout << "position: " << f.tellg() << "\n";
f.read(s, 1);
cout << "got: " << s << "\n";
cout << "position: " << f.tellg() << "\n";
f.close();
return 0;
}
这分别是两个文本文件的两个十六进制编辑器 View :
原始:
修改了:
我希望两者都能分别产生0、1、2的结果,但是原始实验并非如此。
有人可以解释这里发生了什么吗?
问题:
可能的解释(下面由Holt测试答案)
此代码中的f.tellg求助于
f.rdbuf()->pubseekoff(0, ios_base::cur, ios_base::in)
,后者负责产生值0、6、7(但仅当未在施工/开放时指定ios_base::binary
时)。#include <fstream>
#include <iostream>
using namespace std;
static char s[10];
int main(int argc, char **argv)
{
ifstream f("file.txt");
cout << "position: " << f.rdbuf()->pubseekoff(0, ios_base::cur, ios_base::in) << "\n";
f.read(s, 1);
cout << "got: " << s << "\n";
cout << "position: " << f.rdbuf()->pubseekoff(0, ios_base::cur, ios_base::in) << "\n";
f.read(s, 1);
cout << "got: " << s << "\n";
cout << "position: " << f.rdbuf()->pubseekoff(0, ios_base::cur, ios_base::in) << "\n";
f.close();
return 0;
}
注意将
ios::in | ios::binary
作为第二个参数传递给ifstream构造函数,使两个文件的行为均符合预期,但是我也想知道是什么导致默认行为赋予了这些奇怪的Tellg值。请注意与tellg() function give wrong size of file?的区别。这个问题默认设置了ios::binary,并使用seek;这个问题在这里既有ios::binary也有ios::binary,没有使用seek。总体而言,这两个问题具有不同的上下文,并且知道该问题的答案并不能回答该问题。
最佳答案
tellg()
返回的值没有什么“错误”结果:当以文本模式打开文件时,返回值为未指定(即,除了可以用作seekg()
的输入外,它没有其他意义。 )。
基本上,对tellg()
上的basic_fstream
的调用回落到 std::ftell
1函数,该函数表示(C标准,§7.21.9.4[文件定位函数],重点是我的):
1 tellg()
退回到rdbuf()->pubseekoff(0, std::ios_base::cur, std::ios_base::in)
,后者又退回到basic_filebuf::seekoff(0, std::ios_base::cur, std::ios_base::in)
,然后又退回到std::ftell()
。