【c++_文件操作】查看txt文件是否为空/根据空格切割文件内容/修改文件内容

记录使用c++编写机房预约系统的问题和一些技巧

1、查看文件是否为空文件

fstream read_file;
read_file.open(filename,ios::in);
char c;
read_file>>c;
//如果文件为空,返回
if (read_file.eof())
{   
    return 0;
}else{
//不为空,把读出来的字符放回去。进行其他操作
    read_file.putback(c);
}

2、根据空格切割txt文件,存储到vector数组中
方法一:先判断文件是否为空,不为空进行后续操作。使用全局函数getline逐行读取文件内容,存储到temp_data中,再逐行打印。

fstream read_file;
read_file.open(filename,ios::in);
if(!read_file.is_open()){
   
    return 0;
}
//先要判断文件是否为空!!!
char c;
read_file>>c;
if (read_file.eof())
{   
    return 0;
}else{
    read_file.putback(c);
    //逐行对应,空格分割.位置是int类型的
    string temp_data;
    //创建一个数组,来存储切割后的字符串
    while(getline(read_file,temp_data)){
        //直接找用户名会出现重复的失误的情况,应该先切割,再判断是否相同
        int size=temp_data.size();
        int pos=0;
        vector<string> substr;
        for(int i=0;i<size;i++){
            pos=temp_data.find(" ",i); //在i的位置后面按空格找
            if(pos!=-1){
                substr.push_back(temp_data.substr(i,pos-i));
            }else{ //没有空格直接取最后一串字字符串
                substr.push_back(temp_data.substr(i,size));
                break;
            }
            i=i+temp_data.substr(i,pos-i).size();
        }
        //输出
        cout<<numbername<<" :"<<substr.at(0)<<" 姓名: "<<substr.at(1)<<" 密码: "<<substr.at(2)<<endl;
    }
}
read_file.close();

方法二:直接利用读取时候,碰到空格停止的特性分割

while(read_file>>a&&read_file>>b&&read_file>>c&&read_file>>d&&read_file>>e){
            cout<<"预约人 :"<<a<<" 预约日期: "<<b<<" 预约时段: "<<c<<
            " 预约机房: "<<d<<" 预约状态: "<<e<<endl;
        }

3、修改文件内容
方法一:由于文件流不能边读边写,因此使用了临时的txt文件存储修改后的内容. 使用该代码之后还需要覆盖原文件才能达到效果。

//删除了部分代码
//根据名字找记录,count用来计数,等于num时就对了。直接在getline里修改。
int count=0;
string filename=FILENAME;
filename+="order.txt";
string temp_file=FILENAME;
temp_file+="temp_order.txt";
fstream read_file;

fstream out_file;
//不加上in就没办法读到文件
read_file.open(filename,ios::in);
//临时文件
out_file.open(temp_file,ios::out);
if (!read_file.is_open())
{
    cout<<"文件打开失败或不存在!"<<endl;
    system("pause");
    return;
}
//逐行对应,空格分割.位置是int类型的
string temp_data;
//创建一个数组,来存储切割后的字符串
while(getline(read_file,temp_data)){
    //直接找用户名会出现重复的失误的情况,应该先切割,再判断是否相同
    int size=temp_data.size();
    int pos=0;
    vector<string> substr;
    for(int i=0;i<size;i++){
        pos=temp_data.find(" ",i); //在i的位置后面按空格找
        if(pos!=-1){
            substr.push_back(temp_data.substr(i,pos-i));
        }else{ //没有空格直接取最后一串
            substr.push_back(temp_data.substr(i,size));
            break;
        }
        i=i+temp_data.substr(i,pos-i).size();
    }
    if(substr.at(0)==name){
        count++;
        if (count==num)
        { //写入修改后的内容
                out_file<<substr.at(0);out_file<<" ";out_file<<substr.at(1);out_file<<" ";
                out_file<<substr.at(2);out_file<<" ";out_file<<substr.at(3);out_file<<" ";
                out_file<<check_statu;
                char c;
                read_file>>c;
                if (!read_file.eof())
                {   
                    out_file<<endl;
                }
                read_file.putback(c);
        }else{
            //直接整条复制进去
            out_file<<temp_data;
            char c;
            read_file>>c;
            if (!read_file.eof())
            {   
                out_file<<endl;
            }
            read_file.putback(c);
        }
    }
}
read_file.close();
out_file.close();
return;
}

方法二:
在最开始的时候维护一个预约类,初始化该类的时候就读取记录预约的文件。修改的时候修改该状态再保存。保存就是用 out | trunc的方式,重建文件,再写入维护的数据。

4、对比自己的系统和标准系统的启发

  1. 继承的思想
    可以写一个包含编号 姓名 密码的父类,包含一个vitural的登录函数的空实现,让继承该父类的管理员、教师、学生分别实现登录函数,并且可以缩小重复的属性的代码。

2、读取文件
在txt文件中,可以直接用&&符号得到空格分割的子字符串。
例如while(ifs>>a &&ifs>>b &&ifs>>c)

3、在登录的时候,就new了一个对应身份的管理员/教师/学生,后期可以作为参数被传递使用。
传递的时候传的是指针: Identity * & manager 。
可以强制把父类指针转为子类指针,才能调用子类的其他接口: Manager *man= (Manager *) manager.

4、在cpp缺少其他头文件时,可以在它对应的h头文件中包含其他头文件。

5、注销登录之后应该返回最初的登录界面
(return就结束这个函数,回到上一级了;而break只是退出当前的while循环;exit(0)是结束整个程序)

6、在自己编写的有参构造函数中,可以调用一些初始化函数,例如可以加载文件中的一些信息。
(在每次更新文件的时候,都要重新读入文件内容/即重新初始化)

7、在6的基础上,因为在初始化函数中加载了文件的信息,所以可以存储到vector数组中,所以之后显示账号的时候就很方便,直接for_each遍历数组即可。

8、善用嵌套容器。
比如对于预约的属性,可以使用map来进行存储,即键值对的方式。而一条记录则对应多个map格式的数据,可以在其外层嵌套一个map容器来存储(map>)

9、注意substr函数的使用
a.substr(开始截取的位置,要截取的字符数)

10、更新预约的实现
因为在最开始的时候,系统维护了一个记录所有预约的map嵌套容器,所以当修改的时候,会修改该容器的内容,再调用更新接口保存文件即可。利用的是输出流的 out | trunc 模式,即先清空文件再写入新的文件流。这就是实时维护一个数据数组的好处!!!

11、string转化为int
先转化为c语言风格的const char *,再用atoi函数转化。即 atoi(x.c_str())

你可能感兴趣的:(个人学习_研究生,c++,c++,开发语言)