为何代码执行结束时tellg()返回-1?
为什么代码执行结束时tellg()返回-1?
嘿,这个问题其实和C++文件流的状态管理直接相关,我来一步步给你拆解清楚:
核心原因:流处于错误状态时tellg()会返回-1
你的代码里循环条件是while (obj),这个条件本质是检查文件流的状态是否有效。当循环执行到最后一次obj>>ch时:
- 此时文件已经读到了末尾,
>>操作符尝试读取文件结束标记,会触发流的eofbit(文件结束位),同时流的状态会变成失效(布尔值为false)。 - 循环因此退出,但这时候文件流仍然处于错误状态,根据C++标准,此时调用
tellg()会返回pos_type(-1)(也就是你看到的-1),用来表示操作失败。
顺便解释下输出里的“跳号”(比如从5到7)
你输出里的指针位置跳过了6,这是因为>>操作符默认会跳过空白字符(空格、换行、制表符等)。如果你的today.txt里位置6是空格或者换行,obj>>ch会直接跳过它,指针跳到下一个非空白字符的位置,所以输出里看不到6。
怎么获取最后有效的指针位置?
如果你想拿到文件最后一个有效字符的位置,或者文件末尾的真实位置,可以这么修改代码:
#include<iostream> #include<fstream> using namespace std; int main() { system("cls"); fstream obj; obj.open("today.txt", ios::in); char ch; streampos last_valid_pos = 0; // 记录每次成功读取后的位置 // 先尝试读取,读取成功再进入循环 while (obj >> ch) { last_valid_pos = obj.tellg(); cout << endl << "file pointer at :" << last_valid_pos; } // 检查流失效的原因是到达文件末尾 if (obj.eof()) { cout << endl << "End of file reached. Last valid position: " << last_valid_pos; } // 如果想直接获取文件末尾的位置,需要先重置流状态 obj.clear(); // 清除流的错误标记 obj.seekg(0, ios::end); // 跳转到文件末尾 cout << endl << "Total file size (position at end): " << obj.tellg(); return 0; }
这里的关键细节:
- 用
while (obj >> ch)替代原循环,确保只有读取成功时才执行循环体。 - 每次成功读取后记录指针位置,这样即使流最后失效,也能拿到最后有效的位置。
- 如果要在流失效后继续操作(比如跳转到末尾),必须先调用
obj.clear()重置流的错误状态,否则所有操作都会失败。
内容的提问来源于stack exchange,提问作者Mohd Sarim
相关产品推荐
相关产品推荐

