C语言的seekg函数,实战中遇到的C++流文件重置的一个大陷阱: 为什么ifstream的seekg函数无效?...

本文详细介绍了在C++中如何重新从头开始读取文件。在尝试多次使用`seekg()`和`close()`及`open()`函数无效后,作者发现需要使用`in.clear()`来清除文件结束标志,然后使用`seekg(0, ios::beg)`将文件指针重置到开头。最终,成功实现了文件的重新读取。
摘要由CSDN通过智能技术生成

今天下午遇到这样的一个问题: 逐行读取了test.txt文件后,  后续需要继续从头开始重新逐行读取, 用C++怎么做呢?

下面, 我们先在工程当前目录下制作我们需要的test.txt文件, 在里面输入几行字符串:

ab

cd

ef

gh

我们先看逐行读取文件:

#include

#include

#include

using namespace std;

int main()

{

ifstream in("test.txt");

string line;

// 下面代码有效

if(in)

{

while(getline(in, line))

{

cout << line.c_str() << endl;

}

}

return 0;

}

现在, 我们读了一次整个文件后, 又要读, 用下面的方法肯定不行:

#include

#include

#include

using namespace std;

int main()

{

ifstream in("test.txt");

string line;

// 下面代码有效

if(in)

{

while(getline(in, line))

{

cout << line.c_str() << endl;

}

}

// 不会进入下面的if

if(in)

{

cout << "test" << endl;

while(getline(in, line))

{

cout << line.c_str() << endl;

}

}

return 0;

}

回忆一下, 在C语言中, 我们有文件指针重置的概念, 所以这里我们是不是要考虑一下文件重置呢?看:

#include

#include

#include

using namespace std;

int main()

{

ifstream in("test.txt");

string line;

// 下面代码有效

if(in)

{

while(getline(in, line))

{

cout << line.c_str() << endl;

}

}

in.seekg(0, ios::beg); // 指向begin处

// 仍然不会进入下面的if

if(in)

{

cout << "test" << endl;

while(getline(in, line))

{

cout << line.c_str() << endl;

}

}

return 0;

}

还是没有作用, 难道要close然后open? 在C语言中, close并open后, 肯定指向文件头部了, 于是继续尝试:

#include

#include

#include

using namespace std;

int main()

{

ifstream in("test.txt");

string line;

// 下面代码有效

if(in)

{

while(getline(in, line))

{

cout << line.c_str() << endl;

}

}

in.close();

in.open("test.txt");

// 仍然不会进入下面的if

if(in)

{

cout << "test" << endl;

while(getline(in, line))

{

cout << line.c_str() << endl;

}

}

return 0;

}       还是不行, 难道close, open之后还需要seekg? 看:

#include

#include

#include

using namespace std;

int main()

{

ifstream in("test.txt");

string line;

// 下面代码有效

if(in)

{

while(getline(in, line))

{

cout << line.c_str() << endl;

}

}

in.close();

in.open("test.txt");

in.seekg(0, ios::beg); // 指向begin处

// 仍然不会进入下面的if

if(in)

{

cout << "test" << endl;

while(getline(in, line))

{

cout << line.c_str() << endl;

}

}

return 0;

}

还是不行, 邪门了! 不能再鲁莽地尝试了, 查找资料, 终于找到了问题的关键。

看程序:

#include

#include

#include

using namespace std;

int main()

{

ifstream in("test.txt");

string line;

// 下面代码有效

if(in)

{

while(getline(in, line))

{

cout << line.c_str() << endl;

}

}

if(in.eof())

{

cout << "end of file" << endl; // 进入到了这里

}

else

{

cout << "in the file" << endl;

}

return 0;

}

由上面的例子可知, 达到文件尾巴后, 再调用seekg无效, 那怎么办呢? 且看:

#include

#include

#include

using namespace std;

int main()

{

ifstream in("test.txt");

string line;

// 下面代码有效

if(in)

{

while(getline(in, line))

{

cout << line.c_str() << endl;

}

}

in.clear();

if(in.eof())

{

cout << "end of file" << endl;

}

else

{

cout << "in the file" << endl; // 进入到了这里

}

return 0;

}      恩, clear功能真大啊, 好, 我们顺着这个思路继续看:

#include

#include

#include

using namespace std;

int main()

{

ifstream in("test.txt");

string line;

// 下面代码有效

if(in)

{

while(getline(in, line))

{

cout << line.c_str() << endl;

}

}

in.clear();

// 会进入下面的if, 但不会进入while

if(in)

{

cout << "test" << endl;

while(getline(in, line))

{

cout << line.c_str() << endl;

}

}

return 0;

}

恩, 貌似还差点什么吧, 对, 还需要将文件重置到头部, 如下:

#include

#include

#include

using namespace std;

int main()

{

ifstream in("test.txt");

string line;

// 下面代码有效

if(in)

{

while(getline(in, line))

{

cout << line.c_str() << endl;

}

}

in.clear();

in.seekg(0, ios::beg); // 指向begin处

// 会进入下面的if和while

if(in)

{

cout << "test" << endl;

while(getline(in, line)) // 与上面while功能一样

{

cout << line.c_str() << endl;

}

}

return 0;

}

总算是ok了。

最后看一个程序:

#include

#include

#include

using namespace std;

int main()

{

ifstream in("test.txt");

string line;

in.seekg(0, ios::end);

cout << in.tellg() << endl; // 文件大小

if(in.eof())

{

cout << "end of file" << endl;

}

else

{

cout << "in the file" << endl; // 进入到了这里

}

// in the file, 所以下面语句有效

in.seekg(0, ios::beg); // 指向begin处

// 下面代码有效

if(in)

{

while(getline(in, line))

{

cout << line.c_str() << endl;

}

}

return 0;

}

综上所述: seekg(0, ios::end)不是end of file.

end of file的时候, seek是无效的, 必须先clear.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值