异常处理
模板
try{
....//
throw runtime_error();
}catch(exception &e){
cout<<e.what()<<endl;
}
题目
题目描述:
设计一个简单的学生成绩管理系统,要求实现以下功能:
-
学生类(Student):
- 属性:学生姓名、学号、成绩。
- 方法:构造函数、显示学生信息的成员函数showInfo()。
-
学生管理类(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.txt
和friendships.txt
。users.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
,每个学生的信息包括学号(整数)和成绩(浮点数)。你的任务是:
- 读取这个二进制文件中所有学生的信息。
- 修改指定学生的成绩(通过学号找到该学生)。
- 将修改后的信息写回到同一个二进制文件中。
输入示例
二进制文件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
要求
- 你需要处理二进制文件的读取和写入。
- 请注意二进制文件操作与文本文件操作的不同。
- 考虑到性能和效率,尽量减少对文件的读写次数。
这个任务将考验你对二进制文件操作的理解和应用。处理二进制文件时,需要注意如何组织和访问文件中的数据。
代码
#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();
}