【发布时间】:2013-05-18 16:26:51
【问题描述】:
我遇到了 std::fstream 类中的 tellg() 函数的问题。通常它应该返回当前字符在输入流中的位置。但是,它对我来说很奇怪。下面是一些简短的示例代码:
#include <iostream>
#include <fstream>
using namespace std;
int main(void) {
char c;
ifstream czytaj;
czytaj.open("test_file.txt");
cout << czytaj.tellg() << endl; //is 0 should be 0
czytaj.peek(); //is 0 should be 0
cout << czytaj.tellg() << endl; //is 2 should be 0 !!
czytaj.get(c); //is 3 should be 3
czytaj.get(c); //is 4 should be 4
cout << czytaj.tellg() << endl; //is 6 should be 4 !!
int r; cin >> r;
return 0;
}
而 txt 文件如下所示:
abcdefghij
kturjbkfvd
编译后我得到如下输出:
0
2
6
tellg() 的第一次使用正常,它返回位置 0 作为文件的开头。不幸的是,每次下一次使用都会使位置增加+2。结果,我得到了从流中提取的字母“c”和“d”。 tellg() 和 peek() 都应该不改变位置,所以我应该得到字母 'a' 和 'b',而正确的结果应该是:
0
0
2
如果我在 txt 文件中使用编码 ANSI,就会发生这种情况。当我将其更改为 Unicode 时,它可以正常工作。此外,如果我使用 ANSI 和二进制模式 ios::binary,它也可以正常工作。奇怪的事实是,在我的另一台计算机上,即使使用 ANSI 而没有 ios::binary,它也能正常工作。为什么会这样?
编辑:忘记提及非常重要的事实。如果我从此示例代码中删除所有包含 tellg() 的行,则提取是正确的 - 我得到字母 'a' 和 'b'。
【问题讨论】:
-
对我有用 g++4.7.2 libstdc++4.7.2。您使用的是什么编译器/库?
-
它可能是一个 UTF-X 编码的文件,前面有一个 BOM 标记。使用十六进制编辑器转储文件并向我们展示内容。在 Linux 上尝试:
od -t x1 -t c test_file.txt -
您的输入文件是否包含除
abcdefgh之外的任何其他符号?也许换行符或其他什么?难道是文件是Unicode(UTF-16)? -
@Inspired - 是的,它还包含换行符,现在只是在没有换行符的情况下对其进行了测试,即使在 ANSI 和没有二进制模式下也可以正常工作。编辑了我的问题,现在的问题是,为什么换行符会破坏函数tellg()?第一个换行符在第 11 位,即使在第 2 位,它也开始工作错误
-
文本流没有有意义的当前位置。它受 CRT 的影响必须向前看才能正确处理文本编码和字符替换。你离 Unix 和 ASCII 越远,它就越离谱。
标签: c++