文件、异常和操作符重载部分练习

异常处理

模板

try{
    ....//
    throw runtime_error();
}catch(exception &e){
    
    cout<<e.what()<<endl;
}
题目

题目描述:

设计一个简单的学生成绩管理系统,要求实现以下功能:

  1. 学生类(Student):

    • 属性:学生姓名、学号、成绩。
    • 方法:构造函数、显示学生信息的成员函数showInfo()。
  2. 学生管理类(StudentManager):

    • 属性:学生列表(使用 vector 存储学生)。
    • 方法:添加学生的成员函数addStudent(),根据学号查找学生的成员函数findStudent(),删除学生的成员函数deleteStudent(),显示所有学生信息的成员函数showAllStudents()。

要求:

  • 如果添加学生时学号已经存在,则抛出异常并提示学号重复;
  • 如果根据学号查找学生时未找到对应学生,则抛出异常并提示未找到学生;
  • 如果删除学生时未找到对应学生,则抛出异常并提示未找到学生。

请根据上述描述编写程序,并包含必要的异常处理逻辑。

代码

#include<bits/stdc++.h>
using namespace std;

class Student{

protected:
    string name;
    int num;
    int score;

public:
    Student(string name,int num,int score):
        name(name),num(num),score(score){}

    void showInfo()
    {
        cout<<left<<setw(10)<<name<<setw(10)<<num<<setw(10)<<score<<endl;
    }

    int  get_num(){
        return num;
    }
};

class management_Student
{

protected:
    vector<Student> stu;

public:

    void addStudent(Student student)
    {
            for(auto i:stu)
            {
                if(i.get_num()==student.get_num())
                {
                    throw runtime_error("用户已存在");
                }
            }

        stu.push_back(student);
    }

    void findStudent(int num)
    {
        for(auto i:stu)
        {
            if(i.get_num()==num)
            {
                i.showInfo();
                break;
            }
        }
    }

    void deleteStudent(int num)
    {
        for(auto it=stu.begin();it!=stu.end();it++)
        {
            if((*it).get_num()==num)
            {
                stu.erase(it);
            }
        }
    }

    void showAllStudents()
    {
        for(auto i:stu)
        {
            i.showInfo();
        }
    }
};

int main()
{
    try{

        Student stu1("fanbo",1,99);
        Student stu2("zeng",1,999);
        management_Student stuma;
        stuma.addStudent(stu1);
        stuma.addStudent(stu2);
    }catch (exception &e)
    {
        cout<<e.what()<<endl;
    }

}





题目一
题目描述

给定一个CSV文件students.csv,其中包含学生的姓名和他们的分数,格式为姓名,分数(例如Alice,90)。编写一个C++程序,读取这个文件,然后根据分数对学生进行降序排序,最后将排序后的结果写入一个新的CSV文件sorted_students.csv

输入

Alice,82
Bob,95
Charlie,68
Diana,100
Evan,78

输出

Diana,100
Bob,95
Alice,82
Evan,78
Charlie,68

代码

#include<string>
#include<algorithm>
#include<iomanip>
#include<fstream>
#include<stdio.h>
#include<sstream>
#include<iostream>
using namespace std;

struct stu{
	
	string name;
	int score;
};

int change(string ch)
{
	int tmp=0;
	for(int i=0;i<ch.size();i++)
	{
		tmp=tmp*10+ch[i]-'0';
	}
	return tmp;
}

bool cmp(stu a,stu b){
	
	return a.score>b.score;
	
}
int main()
{
	vector<stu> student;

	int num=0;
	ofstream ofs;
	ofs.open("input.txt",ios::out);
	
	ofs<<"Alice"<<","<<82<<endl;
	ofs<<"Bob"<<","<<95<<endl;
	ofs<<"Charlie"<<","<<68<<endl;
	ofs<<"Diana"<<","<<10<<endl;
	ofs<<"Evan"<<","<<78<<endl;
	ofs.close();
	
//	ifstream ifs.open("input.txt",ios::in);
	ifstream ifs;
	ifs.open("input.txt",ios::in);
	
	string sh;
	while(getline(ifs,sh))
	{
		stringstream ss(sh); 
		string ch;
		
		 string namee;
		 int tmp_score;
		while(getline(ss,ch,','))
		{
			//这里的转换函数不记得了  
			if(ch[0]>='0'&&ch[0]<='9')
				tmp_score=change(ch);
			// 不支持	tmp_score=std::stoi(ch);
			else namee=ch;
		}
		student.push_back({namee,tmp_score});
	
	}
	//自定义排序函数 
	sort(student.begin(),student.end(),cmp);
	 
	 ofstream fanbo;
	 fanbo.open("output.txt",ios::out);
	 
	 for(auto it:student)
	 {
	 	fanbo<<it.name<<" "<<it.score<<endl;
	 }
	 
	 fanbo.close();
} 
题目二
题目描述

编写一个C++程序,处理一个模拟社交网络中用户的好友关系。给定两个输入文件:users.txtfriendships.txtusers.txt包含用户的ID和姓名,格式为ID,姓名friendships.txt包含好友关系,格式为用户ID1,用户ID2,表示两个用户是好友(注意:好友关系是双向的)。

你的任务是读取这些数据,然后输出每个用户及其好友数量,按好友数量降序排序。如果两个用户有相同数量的好友,按照用户ID升序排序。将这些信息写入到friendships_summary.txt文件中。

输入示例

user.txt

1,Alice
2,Bob
3,Charlie
4,Diana
5,Evan

friendship.txt

1,2
2,3
3,4
4,5
1,5
2,4

输出 

Bob,3
Diana,3
Alice,2
Charlie,2
Evan,2
代码
#include<iostream>
#include<string>
#include<sstream>
#include<unordered_map>
#include<fstream>
#include<bits/stdc++.h>
using namespace std;

int change(string num)
{
	int ans=0;
	
	for(int i=0;i<num.size();i++)
		ans=ans*10+num[i]-'0';
		
	return ans;
}

struct fan{
	string name;
	int num;
};

bool cmp(fan a,fan b)
{
	if(a.num==b.num)
	{
		return a.name<b.name;
	}
	else{
		return a.num>b.num;
	}
}
int main()
{
	unordered_map<int,string>mp;
	string filename="C:/Users/32255/Desktop/华师复试资料/练习代码/3/users.txt";
	string sh;
	ifstream ifs;
	ifs.open(filename,ios::in);
	
	if(!ifs.is_open())
	{
		cout<<"打开失败"<<endl;
		return 0;
	}
	string ch;
	//建立映射关系 
	while(ifs>>sh)
	{
		stringstream ss(sh);
		int num=0;
		int pos=0;
		string name;
		while(getline(ss,ch,','))
		{
			num++;
			if(num%2!=0)
				pos=change(ch);
			else
				name=ch;
		}
		mp[pos]=name;
		
	}
	ifs.close(); 
	cout<<mp.size()<<endl;
	for(int i=1;i<=mp.size();i++)
	{
		cout<<mp[i]<<endl;
	}
	int a[mp.size()+10]; 
	memset(a,0,sizeof(a));
	//统计数量 
	
	ifstream ifsd;
	
	string filenamee="C:\\Users\\32255\\Desktop\\华师复试资料\\练习代码\\3\\friendships.txt";
	ifsd.open(filenamee,ios::in);
	
	while(ifsd>>sh)
	{
		stringstream ss(sh);
		string tmp;
		
		while(getline(ss,tmp,','))
		{
			a[change(tmp)]++;
		}
	}	
	ifsd.close();
	
	vector<fan>vc;
	
	for(int i=1;i<=mp.size();i++)
	{
			vc.push_back({mp[i],a[i]});
	}
	
	sort(vc.begin(),vc.end(),cmp);	
	
	ofstream of;
	of.open("friendships_summary.txt",ios::out);
	
	for(int i=0;i<vc.size();i++)
	{
		of<<vc[i].name<<","<<vc[i].num<<endl;
	}
}

题目三

题目三:二进制文件的学生成绩管理

假设有一个学生信息的二进制文件students.dat,每个学生的信息包括学号(整数)和成绩(浮点数)。你的任务是:

  1. 读取这个二进制文件中所有学生的信息。
  2. 修改指定学生的成绩(通过学号找到该学生)。
  3. 将修改后的信息写回到同一个二进制文件中。
输入示例

二进制文件students.dat(假设文件已存在,内容为二进制格式,不易于直接查看)。

假设文件中原有的学生信息如下(为了说明方便,这里以文本形式展示):

 

makefileCopy code

学号: 1001, 成绩: 85.5 学号: 1002, 成绩: 90.0 学号: 1003, 成绩: 78.2

你的程序需要提供一个接口(或在程序中直接指定),以便修改指定学生的成绩。例如,将学号为1002的学生成绩修改为92.5。

输出示例

修改后,students.dat文件中的内容应更新为(同样,以文本形式展示以方便说明):

 

makefileCopy code

学号: 1001, 成绩: 85.5 学号: 1002, 成绩: 92.5 学号: 1003, 成绩: 78.2

要求
  1. 你需要处理二进制文件的读取和写入。
  2. 请注意二进制文件操作与文本文件操作的不同。
  3. 考虑到性能和效率,尽量减少对文件的读写次数。

这个任务将考验你对二进制文件操作的理解和应用。处理二进制文件时,需要注意如何组织和访问文件中的数据。

代码
#include<bits/stdc++.h>
using namespace std;

struct stu{
	
	int num;//学号
	double scores;
	 
};

int main() 
{
	
	//写数据 
	ofstream ofs;
	ofs.open("students.dat",ios::out|ios::binary);
	
	stu student[3]={
		{1001,  85.5},
		{1002, 90.0},
		{1003,  78.2},
	};
	
	for(int i=0;i<3;i++)
	{
		ofs.write(( char *)&student[i],sizeof(student[i]));
	}
	
	ofs.close();
	
	//修改数据 
	fstream fs;
	fs.open("students.dat",ios::in|ios::out|ios::binary);
	int number;
	double sco;
	cout<<"请输入你要修改的学生的学号和分数"<<endl;
	cin>>number>>sco;
	
	stu tmp_student;
	while(fs.read((char *)&tmp_student,sizeof(tmp_student)))
	{
		if(tmp_student.num==number)
		{
			tmp_student.scores=sco;
			//这个地方很奇怪 
			fs.seekp(-static_cast<int>(sizeof(tmp_student)),ios::cur);
			 //fs.seekp(-static_cast<int>(sizeof(tmp_student)), ios::cur);
			fs.write((char *)&tmp_student,sizeof(tmp_student));
			break;
		}
	}
	fs.close();
	
	ifstream iff;
	iff.open("students.dat",ios::binary|ios::in);
	
	while(iff.read((char *)&tmp_student,sizeof(tmp_student)))
	{
		cout<<tmp_student.num<<" "<<tmp_student.scores<<endl;
	}
	iff.close();
	
	
}    

题目四:编写一个程序,读取名为inventory.txt的文本文件,文件中每行包含商品名称和库存数量(用逗号分隔),例如:"Apple,100"。然后用户可以输入要购买的商品名称和数量,程序将检查库存是否足够,如果库存充足,则更新库存并将购买记录写入名为purchase_history.txt的文本文件中,每行格式为购买时间 商品名称 购买数量;如果库存不足,则输出提示信息。 

//编写一个程序,读取名为inventory.txt的文本文件,
//文件中每行包含商品名称和库存数量(用逗号分隔),
//例如:"Apple,100"。然后用户可以输入要购买的商品名称和数量
//程序将检查库存是否足够,如果库存充足,
//则更新库存并将购买记录写入名为purchase_history.txt的文本文件中
//每行格式为购买时间 商品名称 购买数量;如果库存不足,则输出提示信息。
//

#include<iostream>
#include<fstream>
using namespace std;

struct Food
{
    string name;
    int num;
};
int main()
{

    Food food[5]={
        {"Apple",100},
        {"Banana",50},
        {"Orange",75},
        {"Mango",30},
        {"Pineapple",20}
    };

    ofstream ofs;
    ofs.open("inventory.txt",ios::out|ios::binary);

    for(int i=0;i<5;i++)
    {
        ofs.write((char *)&food[i],sizeof(food[i]));
    }
    ofs.close();
    cout<<"请输入你想购买的事物以及其数量"<<endl;
    string goods;
    int num;
    cin>>goods>>num;

    fstream fs;
    fs.open("inventory.txt",ios::in|ios::out|ios::binary);

    Food buy;
    while(fs.read((char*)&buy,sizeof(buy)))
    {
        if(buy.name==goods)
        {
            if(buy.num>=num)
            {
                Food tmp;
                tmp.name=buy.name;
                tmp.num=buy.num-num;
                //修改原库存
                fs.seekp(-sizeof(buy),ios::cur);
                fs.write((char *)&tmp,sizeof(tmp));
                fs.close();
                //写入购买记录
                ofstream pur;
                pur.open("purchase_history.txt",ios::out);
                pur<<goods<<" "<<num<<endl;
            }
            else
            {
                cout<<"库存不足"<<endl;
                return 0;
            }
        }
    }
    fs.open("inventory.txt",ios::in|ios::out|ios::binary);
    while(fs.read((char*)&buy,sizeof(buy)))
    {
        cout<<buy.name<<" "<<buy.num<<endl;
    }


}

题目五(重点)

总结:

就是对于这种列数不多的 当把他们转换成流的时候 可以直接一个一个单词的读 不要用循环 考试数据大概率也不会太大,一行一行读操作简单 代码可读性好,以后要一行一行读了)

对于这种题目经常用流 +结构体 +vector +sort排序 理解就好

题目描述

编写一个程序,读取名为sales.csv的CSV格式文件,文件中包含销售数据,每行数据包含日期、商品名称、销售数量和销售金额等信息。程序要求计算每种商品的总销售数量和总销售金额,并将计算结果按照销售金额从高到低的顺序写入名为sales_summary.csv的CSV文件中,每行格式为商品名称,总销售数量,总销售金额。给我一些样例让我将数据写进去 

代码

//编写一个程序,读取名为sales.csv的CSV格式文件
//文件中包含销售数据,每行数据包含日期、商品名称
//、销售数量和销售金额等信息。程序要求计算每种商
//品的总销售数量和总销售金额,并将计算结果按照
//销售金额从高到低的顺序写入名为sales_summary.
//csv的CSV文件中,每行格式为商品名称,总销售数量
//,总销售金额。

#include<bits/stdc++.h>
using namespace std;
struct total
{
    string name;
    int num;
    int sum;
};

int change(string ch)
{
    int ans=0;

    for(int i=0;i<ch.size();i++)
    {
        ans=ans*10+ch[i]-'0';
    }
    return ans;
}

bool cmp(total x,total y)
{
    return x.sum>y.sum;
}
int main()
{
    ofstream ofs;
    ofs.open("sales.csv",ios::out);

       ofs<< "日期,商品名称,销售数量,销售金额"<<endl;
        ofs<<"2024-01-01,Apple,100,5000"<<endl;
       ofs<< "2024-01-02,Banana,150,3000"<<endl;
        ofs<<"2024-01-03,Apple,200,8000"<<endl;
        ofs<<"2024-01-04,Orange,120,6000"<<endl;
       ofs<< "2024-01-05,Banana,180,4500"<<endl;
        ofs<<"2024-01-06,Apple,150,6000"<<endl;
        ofs<<"2024-01-07,Orange,140,7000"<<endl;
        ofs.close();

        unordered_map<string ,int>mp_num;
        unordered_map<string,int>mp_sum;

        ifstream ifs;
        ifs.open("sales.csv",ios::in);
        string ch;
        getline(ifs,ch);//读出标题栏

        vector<total>vc;
        while(getline(ifs,ch))
        {
            stringstream ss(ch);
            string data,name,tmp;
            int num,sum;
            //从这一题中你要知道 不要总是记得用循环 列数不多时 直接一行一行取
            //我感觉就要这样 可以减轻思考量
            getline(ss,data,',');
            getline(ss,name,',');
            getline(ss,tmp,',');
            num=stoi(tmp);
//            num=change(tmp);
            getline(ss,tmp,',');
//            sum=change(tmp);

            mp_num[name]+=num;
            mp_sum[name]+=sum;

        }
        ifs.close();

        for(auto i:mp_sum)
        {
            vc.push_back({i.first,mp_num[i.first],i.second});
        }
        sort(vc.begin(),vc.end(),cmp);

        ofstream offs;
        offs.open("sales_summary.csv",ios::out);

        for(int i=0;i<vc.size();i++)
        {
            offs<<vc[i].name<<","<<vc[i].num<<","<<vc[i].sum<<endl;
        }

        offs.close();



}

题目六 统计单词

 

#include<iostream>
#include<fstream>
#include<unordered_map>
#include<vector>
#include<algorithm>
#include<sstream>
using namespace std;

struct word
{
    string str;
    int number;


};

bool cpm(word & a,word &b)
{
    return a.number>b.number;
}

string change(string str)
{
    string cpy;
    for(int i=0;i<str.size();i++)
    {
        if(str[i]>='a'&&str[i]<='z'||str[i]>='A'&&str[i]<='Z')
            cpy+=str[i];
    }

    return cpy;
}
int main()
{
    ifstream ifs;
    ifs.open("word.txt",ios::in);

    unordered_map<string,int>mp;

    string sh;//用来存一行一行的数据

    while(getline(ifs,sh))
    {
        stringstream ss(sh);//转换成流
        string ch;
        while(getline(ss,ch,' '))
        {
            ch=change(ch);
            if(ch.size()==0)
                continue;
            mp[ch]++;
        }
    }

    ifs.close();

    vector<word>vc;

    for(auto it:mp)
    {
        vc.push_back({it.first,it.second});
    }

    sort(vc.begin(),vc.end(),cpm);

    ofstream ofs;
    ofs.open("fanbo.txt",ios::out);

    for(int i=0;i<vc.size();i++)
    {
        ofs<<vc[i].str<<","<<vc[i].number<<endl;
    }


}

未完成

#include <iostream>
#include <fstream>
using namespace std;

struct Student {
    int num;
    char name[20];
    int age;
    double avg;
};

int main() {
    Student stu[3] = {
        {1, "fanbo", 17, 99},
        {2, "bo", 17, 9},
        {4, "fbo", 144, 60}
    };

    ofstream ofs("data.bin", ios::out | ios::binary);
    for (int i = 0; i < 3; i++) {
        ofs.write((char*)&stu[i], sizeof(stu[i]));
    }
    ofs.close();

    ifstream ifs("data.bin", ios::in | ios::binary);
    fstream afs("even_students.bin", ios::out| ios::binary);

    Student st;
    while (ifs.read((char*)&st, sizeof(st))) {
        if (st.num % 2 == 0) {
            afs.seekp(0, ios::end);  // 将文件指针移动到文件末尾
            afs.write((char*)&st, sizeof(st));
        }
    }

    ifs.close();
    afs.clear();  // 清除文件流状态

    afs.open("even_students.bin", ios::in | ios::out | ios::binary);
    while (afs.read((char*)&st, sizeof(st))) {
        cout << st.name << " " << st.avg << endl;
        st.avg += 10;
        afs.seekp(-sizeof(st), ios::cur);
        afs.write((char*)&st, sizeof(st));
    }
    afs.close();

    afs.open("even_students.bin", ios::in | ios::binary);
    while (afs.read((char*)&st, sizeof(st))) {
        cout << st.name << " " << st.avg << endl;
    }

    return 0;
}

操作符重载

#include<bits/stdc++.h>

using namespace std;
class Wache{

public:

    int minute;
    int second;


public:
    Wache(){}
    Wache(int mi,int se):minute(mi),second(se){}
    //重载+号操作
    Wache operator + (Wache & p)
    {
        Wache a;
        a.second =this->second+p.second;
        a.minute=this->minute+p.minute;
        if(a.second>=60)
        {
            a.second-=60;
            a.minute++;
        }
        return a;
    }

    //重载++操作(先++) 前置
    Wache operator ++()
    {
        this->second++;
        return *(this);
    }

    //后置 后置这里要用int搞个占位符
    Wache operator ++(int)
    {
        Wache tmp= (*this);
        this->second++;
        if(this->second>60)
        {
            this->second-=60;
            this->minute++;
        }
        return tmp;
    }

    void operator =(Wache p)
    {
        this->minute=p.minute;
        this->second=p.second;
    }

    void getInfo()
    {
        cout<<minute<<" "<<second<<endl;
    }
};

int main()
{
    Wache wa(12,32);
    Wache wc=wa++;
    wc.getInfo();
    ++wa;
    wa.getInfo();
    //复制操作重载
    Wache wb=wa;
//    wb.getInfo();

    Wache wd=wa+wb;
    wd.getInfo();
}

  • 29
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值