我正在玩 ifstream 来熟悉它。我正在尝试使用 seekg 来告诉文件的位置,但它给了我错误的结果。
这个想法是:
- 打开文件
- 文件的打印位置
- 从文件中读取一个字符
- 文件的打印位置
- 从文件中读取一个字符
- 文件的打印位置
- 关闭文件。
原始文件如下所示(windows 格式):
文件.txt
aA
bB
cC
dD
eE
fF
运行我的代码,我得到了结果:
position: 0
got: a
position: 6
got: A
position: 7
但是,对于这个文件:
文件.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")
构造函数。
- 是什么导致 f.tellg 默认给出这些奇怪的值 0,6,7 而不是预期的 1,2,3?
可能的解释(测试下面 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() 函数的区别给出错误的文件大小?. 该问题默认设置了 ios::binary ,并使用 seek; 这里的这个问题有 ios::binary 和没有,并且不使用 seek。总的来说,这两个问题有不同的背景,知道该问题的答案并不能回答这个问题。