接上一篇:点击打开链接
准备工作:
fstream p;
p.open("C:\\Users\\用户名\\Desktop\\hh.txt");
if(!p.is_open()){
cout<<"打开失败我靠什么情况"<<endl;
exit(1);
}
开篇一个混吃等死管理系统:
struct student
{
string name;
int id;
char gender;
student(string ts, int ti, char tc):name(ts),id(ti),gender(tc){} //ts就是临时string,以此类推
student()=default;
};
使用stl中的list来储存student:
list<student> guys;
定义一个input函数来输入:
void inputs(list<student> &guys)
{
student temps; //有没有不定义临时的变量的方法?
while(cin>>temps.name){ //输入 control + z 结束
cin>>temps.id>>temps.gender;
guys.push_back(temps);
}
}
暴力输出全部文件内容:
char cs[100];
p.getline(cs,100,'\0');
cout<<cs;
上面都没什么好玩的
目标:
掌握文件指针
在文件中排序
替换任意学生的信息
等等
实现:
文件操作其中一个重要的公用就是,以能简易的修改文件的形式,来修改程序所需要的输入,于是就不需要每次都在黑框里打出大量的数据了,也不必直接修改源代码,省去了不必要的编译;
显然楼上的暴力方法没什么用,必须把文件内容转化为 内存内的 复杂的 数据
例如将文件内容写入student类中:
list<student> guys;
student temp; //临时的学生变量
while(!p.eof()){ //读到文件尾部返回true
p>>temp.name>>temp.id>>temp.gender; //利用>>只会读到空白符的特点
guys.push_back(temp);
}
for(auto &guy:guys){ //11新标准
cout<<guy.name<<ends<<guy.id<<ends<<guy.gender<<endl; //全部输出list内的数据;
}
文件内容:
黑框:
这下可好,两个Liza;something happened;
根据网上查找的资料,eof函数指向的是文件尾部最后一个字符之后的时候返回true,也就是在此之前会将文件指针所指的地方再次读入一遍。。。居然把整个类读了两遍;
根据网上的方法,将p.eof()改为p.peek() != EOF,结果鸟用没有,效果一样
。。。
解决方法:(待补充)->已补充
。。。
凑合方法:在while语句后面加上一个 guys.pop_back();
就能删除最后重复的数据;
--------------------------------------------------------
本方法完美避免重复读取文件尾部的数据
streampos pp,endpp;
p.seekg(0,ios::end);
endpp=p.tellg(); //保存文件尾部指针
p.seekg(0,ios::beg);
//cout<<"the end point : "<<endpp<<endl;
while(p.tellg()<endpp-1){ //g++ 有警告,是不明确行为,改为(static_cast<int>(p.tellg())<static_cast<int>(endpp)-1)
p>>temp.name>>temp.id>>temp.gender;
guys.push_back(temp);
pp=p.tellg(); //更新当前文件指针
//cout<<"now the point : "<<pp<<endl;
}
本次利用的是文件指针来判断是否读取到文件尾部
发现p.seekg(0,ios:end)返回的总是文件读完后的数字+1,
------------------------------------------------------------
再次更新:强制类型转换还是越少越好
streampos pp,endpp;
p.seekg(-1,ios::end); //直接改指向前一个位置
endpp=p.tellg();
p.seekg(0,ios::beg);
cout<<"now the point : "<<endpp<<endl;
while(p.tellg()<endpp){ //省去了类型转换
p>>temp.name>>temp.id>>temp.gender;
guys.push_back(temp);
pp=p.tellg();
cout<<"now the point : "<<pp<<endl;
}
完整源文件
#include <iostream>
#include <fstream>
#include <string>
#include <list>
using namespace std;
struct student
{
string name;
int id;
char gender;
student(string ts, int ti, char tc):name(ts),id(ti),gender(tc){}
student()=default;
};
void inputs(list<student> &guys)
{
student temps;
while(cin>>temps.name){
cin>>temps.id>>temps.gender;
guys.push_back(temps);
}
}
int main()
{
fstream p;
p.open("C:\\Users\\用户名\\Desktop\\hh.txt");
if(!p.is_open()){
cout<<"打开失败我靠什么情况"<<endl;
exit(1);
}
list<student> guys;
student temp;
streampos pp,endpp;
p.seekg(-1,ios::end);
endpp=p.tellg();
p.seekg(0,ios::beg);
cout<<"now the point : "<<endpp<<endl;
while(p.tellg()<endpp){
p>>temp.name>>temp.id>>temp.gender;
guys.push_back(temp);
pp=p.tellg();
cout<<"now the point : "<<pp<<endl;
}
//guys.pop_back();
for(auto &guy:guys){
cout<<guy.name<<ends<<guy.id<<ends<<guy.gender<<endl;
}
p.close();
return 0;
}