我正在玩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
#include
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;
}
以下是两个文本文件的两个十六进制编辑器视图:
original :
modified :
我希望两者分别得到结果0,1,2,但原始实验并非如此 .
有人可以解释这里发生了什么吗?
Questions :
如何获得正确的文件位置?
答案:在ifstream(“file.txt”)构造函数上使用ifstream(“file.txt”,ios_base :: in | ios_base :: binary)构造函数 .
是什么导致f.tellg默认给出这些奇怪的值0,6,7而不是预期的1,2,3?
possible explanation (测试Holt的答案如下)
此代码中的f.tellg转换为 f.rdbuf()->pubseekoff(0, ios_base::cur, ios_base::in) ,它负责生成值0,6,7(但仅当在构造/打开时未指定 ios_base::binary 时) .
#include
#include
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;
}
Note 传递 ios::in | ios::binary 作为ifstream构造函数的第二个参数使两个文件按预期运行,但我也想知道是什么导致默认行为给出这些奇怪的tellg值 .
Note 与tellg() function give wrong size of file?的区别 . 那个问题默认设置为ios :: binary,并使用seek;这个问题在这里有ios :: binary和without,并且不使用seek . 总的来说,这两个问题有不同的背景,知道这个问题的答案并没有回答这个问题 .