我正在玩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;
}
以下是两个文本文件的两个十六进制编辑器视图:
我希望两者分别得到结果0,1,2,但原始实验不是这样。
有人能解释一下这里发生了什么吗?
问题:
答案:在
ifstream("file.txt", ios_base::in | ios_base::binary)
构造函数上使用ifstream("file.txt")
构造函数。
可能的解释(在下面测试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和without,并且不使用seek。总的来说,这两个问题有不同的背景,知道这个问题的答案并没有回答这个问题。
答案 0 :(得分:5)
tellg()
返回的值没有“错误”结果:当文件以文字模式打开时,返回值未指定(即它没有任何意义,除了它可以用作seekg()
)的输入。
基本上,tellg()
上对basic_fstream
的调用会回退到std::ftell
1 函数,该函数表示(C标准,§7.21.9.4[文件定位功能],重点是我的):
long int ftell(FILE *stream);
ftell
函数获取stream
指向的流的文件位置指示符的当前值。 [...]对于文本流,其文件位置指示符包含未指定的信息,fseek
函数可用于返回文件位置指示符 在ftell
电话时流到其位置;两个这样的返回值之间的差异不一定是写入或读取的字符数的有意义的度量。
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()
。子>