假定有 n 门课程,每门课程有:课程编号,课程名称,课程性质(公共课、必修
课、选修课),总学时,授课学时,实验或上机学时,学分,开课学期等信息。试设
计一课程管理系统,使之能具有以下功能:
(1)系统以菜单方式工作
(2)课程信息录入功能
(3)课程信息浏览功能
(4)课程信息查询功能
(5)课程信息的删除
(6)课程信息的插入
(7)将课程信息写入文件中
(8)从文件中导出课程信息
#include
#include
#include
#include
#include
#include
#include
using namespace std;
//课程编号
//课程名称
//课程性质
//总学时
//授课学时
//实验或上级学时
//开课学期
//学分
//指向上一个指针,模板上没有这个指针,但我感觉有用,先留着。
//防止野指针的出现
struct kcxx
{
int kcbh;
char kcmc[30];
char kcxz[30];
int zxs;
int skxs;
int syhsjxs;
int kxxq;
int xf;
//指向下一个元素的指针
//KeCheng *Head;
};
struct KeCheng
{
kcxx mql;
KeCheng *next=NULL;
};
class HH{
public:
void luru();
void liulan();
void chaxun();
void shanchu();
void charu();
void xierudaowenjian();
void daochudaohanshu();
void paixu();
KeCheng *head = NULL;
KeCheng *p = NULL;
}HH1;
//防止野指针的出现
//防止野指针的出现
void HH::luru()
时才需要录入,已经有信息是就不用这个函数
{
p = new KeCheng; head = p; KeCheng *p2;
cout << "请输入课程编号:"; cin >> p->mql.kcbh;
while (p->mql.kcbh != 0)
{
//信息录入 注:第一次输入
cout << "请输入课程名称:"; cin >> p->mql.kcmc;
cout << "请输入课程性质:(gongkaike; xuanxuke ;bixiuke)"; cin >> p->mql.kcxz;
cout << "请注意:以下数据类型为 int 型,只能输入数字哦,不然会出错的哦!" << endl;
cout << "请输入总学时在:"; cin >> p->mql.zxs;
cout << "请输入授课学时:"; cin >> p->mql.skxs;
cout << "请输入实验或上机学时:"; cin >> p->mql.syhsjxs;
cout << "请输入学分:"; cin >> p->mql.xf;
cout << "请开课学期"; cin >> p->mql.kxxq;
cout << "ok! 您已输入成功!" << endl;
p2 = p;
//保存 p 的地址,以便可以再次使用 p 指针,同时不丢失现有地址
cout << "如果想继续输入的话,请输入下一个课程的编号。如果想退出的话,请输入 0" << endl;
cout << "请输入你的选择:";
p = new KeCheng; cin >> p->mql.kcbh; if (p->mql.kcbh != 0) p2->next = p;
//else p2->next = NULL;这句被我去掉了
}
}
void HH::liulan()
{
if (HH1.head == NULL) {
//信息浏览
cout << "你还没把信息输入进去!";
char d; cout << "请输入一个数字或英文字符,退回主菜单"; cin >> d;
}
else {
KeCheng *k = head;
cout << setiosflags(ios::left) << setw(10) << "课程编号" << setiosflags(ios::left) <<
setw(15) << "课程名称" << setiosflags(ios::left) << setw(15) << "课程性质";
cout << setiosflags(ios::left) << setw(5) << "总学时" << setiosflags(ios::left) <<
setw(5) << "上机或实验学时";
cout << setiosflags(ios::left) << setw(5) << "学分" << setiosflags(ios::left) << setw(5)
<< "开课学期" << endl;
while (k)
{
cout << setiosflags(ios::left) << setw(10) << k->mql.kcbh <<
setiosflags(ios::left) << setw(15) << k->mql.kcmc << setiosflags(ios::left) << setw(15) <<
k->mql.kcxz;
cout << setiosflags(ios::left) << setw(5) << k->mql.zxs << setiosflags(ios::left)
<< setw(5) << k->mql.syhsjxs;
cout << setiosflags(ios::left) << setw(5) << k->mql.xf << setiosflags(ios::left)
<< setw(5) << k->mql.kxxq << endl;
k = k->next;
}char d; cout << "请输入一个数字或英文字符,回到主菜单"; cin >> d;
}
}
void HH::chaxun()
查询,这里有编号的查询,名称的查询,还可以加入其他查询,但是实用性不高。
{
//信息的
cout << " 请选择查询方法:1.按课程编号查询;2.按课程名称查询。请输入选项对应号码。" << endl;
int a, Q = 1, w = 0; cin >> a;
//w 一会用来判断
是否查询到对应课程
if (a == 1)
{
cout << "请输入你查询的课程的编号(00001-99999),或者输入 0 退回主菜单:" << endl; cin >>
Q;
while (Q)
//此处以 Q 为判断是否执行按
编号查询的循环, 注:课程的编号默认为都大于 0 (这是后加的贴心小功能,如果用户不想查询了,
可以直接退出)
{
KeCheng *k = head;
while (k)
{
if (k->mql.kcbh == Q)
{
cout << "查询到的课程的具体信息为:";
//按编号查询的具体过程
cout << setiosflags(ios::left) << setw(10) << "课程编号" <<
setiosflags(ios::left) << setw(15) << "课程名称" << setiosflags(ios::left) << setw(15) << "
课程性质";
cout << setiosflags(ios::left) << setw(5) << "总学时" <<
setiosflags(ios::left) << setw(5) << "上机或实验学时";
setiosflags(ios::left) << setw(5) << "开课学期" << endl;
cout << setiosflags(ios::left) << setw(5) << "学分" <<
cout << setiosflags(ios::left) << setw(10) << k->mql.kcbh <<
setiosflags(ios::left) << setw(15) << k->mql.kcmc << setiosflags(ios::left) << setw(15) <<
k->mql.kcxz;
cout << setiosflags(ios::left) << setw(5) << k->mql.zxs <<
setiosflags(ios::left) << setw(5) << k->mql.syhsjxs;
cout << setiosflags(ios::left) << setw(5) << k->mql.xf <<
setiosflags(ios::left) << setw(5) << k->mql.kxxq << endl;
w = 1;
break;
}
else k = k->next;
}if (!w)cout << " 对不起,你所查询的课程不存在!" << endl << "请重新输入课程编
号,或者输入“0”回到主菜单";
cin >> Q;
}
}
if (a == 2)
查询
{
//按课程名称
cout << "温馨提示:如果你查询的课程名称过长,推荐你选择编号查询!" << endl;
cout << "请输入你想要查询的课程的名称,或者输入“jieshu”回到主菜单" << endl;
char name[30];
int w = 0;
cin >> name;
//w 作
为判断是否找到对应的课程的依据
char jieshu[] = "jieshu";
数组作为判断客户是否要退出的依据
do{if (strcmp(jieshu, name) == 0)break;
加的贴心小功能,如果用户不想查询了,可以直接退出
KeCheng *k = head;
while (k)
{
if (strcmp(k->mql.kcmc, name) == 0)
//按名称查询的具体比较过程
{
w = 1;
//这个
//这是后
cout << "查询到的课程的具体信息为:";
cout << setiosflags(ios::left) << setw(10) << "课程编号" <<
setiosflags(ios::left) << setw(15) << "课程名称" << setiosflags(ios::left) << setw(15) << "
课程性质";
cout << setiosflags(ios::left) << setw(5) << "总学时" <<
setiosflags(ios::left) << setw(5) << "上机或实验学时";
cout << setiosflags(ios::left) << setw(5) << "学分" <<
setiosflags(ios::left) << setw(5) << "开课学期" << endl;
cout << setiosflags(ios::left) << setw(10) << k->mql.kcbh <<
setiosflags(ios::left) << setw(15) << k->mql.kcmc << setiosflags(ios::left) << setw(15) <<
k->mql.kcxz;
cout << setiosflags(ios::left) << setw(5) << k->mql.zxs <<
setiosflags(ios::left) << setw(5) << k->mql.syhsjxs;
cout << setiosflags(ios::left) << setw(5) << k->mql.xf <<
setiosflags(ios::left) << setw(5) << k->mql.kxxq << endl;
break;
}
else k = k->next;
}
if (!w)cout << "对不起,你查询的课程不存在,请重新输入,或者输入“jieshu”回到
主菜单";
else cout << "查询成功!如果想继续查询,请继续输入课程名称,或者输入“jieshu”
回到主菜单" << endl;
cin >> name;
} while (!(strcmp(name, jieshu) == 0));
}
}
void HH::shanchu()
{
//删除课程信息
if (head == NULL)cout << "数据为空,删除失败!!!!" << endl;
else
{
KeCheng *p1, *p2; p1 = head; p2 = head->next;
cout << "请输入想要删除的课程的课号:";
int a, n = 0; cin >> a;
KeCheng *linshi = head;
while (linshi != NULL)
{
n++;
if (linshi->mql.kcbh == a)break;
linshi = linshi->next;
}
if (linshi == NULL)cout << "不存在此课程,删除出错!!!!" << endl;
else
//这是删除的具体函数,我结合老师讲
的思想,模板的做法,还有自己的想法,对原来的错误做出了改正
{
if (linshi == head){ head = head->next; }
else{
int i;
for (i = 0; i < n-1; i++)
{
p1 = p2; p2 = p2->next;
}
if (p2 == NULL)p1 = NULL;
else p1->next = p2->next;
}
cout << "删除成功!!!!" << endl; char d; cout << "请输入一个数字或英文字符,回
到主菜单"; cin >> d;
}
}
}
void HH::charu()
{
p = new KeCheng;
cout << " 请输入你想插入的课程的编号"; cin >> p->mql.kcbh; cout << endl;
KeCheng *k; k = head;
int a = 1;
while (!(k == NULL))
//判断用户想要插入的课程是否
已存在
{
if (k->mql.kcbh == p->mql.kcbh){ cout << "此课程已存在,插入有误!!!!!"<> d; break; };
k = k->next;
}
if (a)
{
cout << "请输入课程名称:"; cin >> p->mql.kcmc; cout << endl;
cout << "请输入课程性质:"; cin >> p->mql.kcxz; cout << endl;
cout << "请输入总学时:"; cin >> p->mql.zxs; cout << endl;
cout << "请输入授课学时:"; cin >> p->mql.skxs; cout << endl;
cout << "请输入实验或上机学时:"; cin >> p->mql.syhsjxs; cout << endl;
cout << "请输入开学学期:"; cin >> p->mql.kxxq; cout << endl;
cout << "请输入学分:"; cin >> p->mql.xf; cout << endl;
p->next = head; head = p;
cout << "插入成功!!!!!!" << endl; char d; cout << "请输入一个数字或英文字符,回到
//将这个结构体连接到链表上;
主菜单"; cin >> d;
}
}
void HH::xierudaowenjian()
{
KeCheng *s = head;
ofstream fop;
fop.open("课程信息.dat",
if (!fop)
{
ios::out);
//这里准备直接把这个函数镶嵌在其他函数里
cout << "课程信息.dat 无法打开!" << endl;
abort();
}
while (s)
{
fop.write((char *)&s->mql, sizeof(s->mql));
s = s->next;
}
fop.close();
}
void HH::daochudaohanshu()
{
{ p = new KeCheng;
ifstream fip("课程信息.dat", ios::in | ios::binary);
if (!fip)cout << "文件打开失败!" << endl;
else
while (fip.read((char *)&p->mql, sizeof(p->mql)))
{
p->next = head;
head = p;
p = new KeCheng;
}
fip.close();
delete p;
}cout << "导出成功!" << endl;
}
void HH::paixu()
{
个对象交换内容。其实我最初想的方法是让两个对象交换
//此处使用了一个简单的冒泡法,虽然看着程序很复杂,但实际上原理很简单,就是让两
//将课程按照编号,从小到大排序。
//地址,这样看着简单,但是地址的交换很复杂,需要分的情况很多:1.两个对象连续时.2。
两个对象之间隔了一个元素时。3.两个对象隔了两个,及以上
//对象时。4.两个对象在头或尾,或在中间时。。。。。。很多情况,很难写,而且就算我写了出来,别
人也看不懂。违反了程序易懂的原则,得不偿失。
KeCheng *p1, *p2 = NULL , *p3 = NULL; int i;
p1 = head;
while (p1 != NULL)
{ p2 = p1->next;
while (p2 != NULL)
{
if (p1->mql.kcbh > p2->mql.kcbh)
{
p3->mql.kcbh;
p3->mql.kcbh = p1->mql.kcbh; p1->mql.kcbh = p2->mql.kcbh; p2->mql.kcbh =
//交换课程编号
课程名称
交换课程性质
{for (i = 0;i<30; i++)p3->mql.kcmc[i] = p1->mql.kcmc[i];
//交换
for (i = 0;i<30; i++)p1->mql.kcmc[i] = p2->mql.kcmc[i];
for (i = 0; i<30; i++)p2->mql.kcmc[i] = p3->mql.kcmc[i]; }
{for (i = 0; i<30; i++)p3->mql.kcxz[i] = p1->mql.kcxz[i];
//
for (i = 0; i<30; i++)p1->mql.kcxz[i] = p2->mql.kcxz[i];
for (i = 0;i<30; i++)p2->mql.kcxz[i] = p3->mql.kcxz[i]; }
p3->mql.zxs;
p3->mql.zxs = p1->mql.zxs; p1->mql.zxs = p2->mql.zxs; p2->mql.zxs =
//交换总学时
p3->mql.skxs;
p3->mql.skxs = p1->mql.skxs; p1->mql.skxs = p2->mql.skxs; p2->mql.skxs =
//交换授课学时
p2->mql.syhsjxs = p3->mql.syhsjxs;
//交换实验或上机学时
p3->mql.syhsjxs = p1->mql.syhsjxs; p1->mql.syhsjxs = p2->mql.syhsjxs;
//交换学分
p3->mql.xf = p1->mql.xf; p1->mql.xf = p2->mql.xf; p2->mql.xf = p3->mql.xf;
p3->mql.kxxq = p1->mql.kxxq; p1->mql.kxxq = p2->mql.kxxq; p2->mql.kxxq =
p3->mql.kxxq;
//交换开课学期
}
p2 = p2->next;
}p1 = p1 ->next;
}
}
int glycd()
{
do{
//管理员的菜单界面
//清屏
操作方式:
1.信息录入
system("cls");
cout << "\t\t********************************************\n"
<< "\t\t*
*\n"
<< "\t\t******欢迎使用江西理工大学课程管理系统******\n"
<< "\t\t********************************************\n"
<< "\t\t*
*\n"
*\n"
<< "\t\t*
*\n"
<< "\t\t*
*\n"
<< "\t\t*
<< "\t\t*
*\n"
*\n"
<< "\t\t*
*\n"
<< "\t\t*
*\n"
<< "\t\t*
<< "\t\t*
*\n"
*\n"
<< "\t\t*
*\n"
<< "\t\t*
*\n"
<< "\t\t*
*\n"
<< "\t\t*
<< "\t\t*
*\n"
*\n"
<< "\t\t*
<< "\t\t*
*\n"
<< "\t\t********************************************\n";
6.导出信息到文件中
7.导入文件中的信息
5.信息的插入
2.信息浏览
3.信息查询
4.信息删除
cout << "\t\t 请选择操作方式: " << endl;
int a; cin >> a;
if (a >= 1 && a <= 7){ return a; break; }
else cout << "您输入的数值有误!!!请重新输入:";
//这里有个问题,当我输入有误时,界面总是一闪而过
} while (1);
}
void ykcd()
{
int a;
do{
do{
//学生的菜单界面
//清屏
system("cls");
cout << "\t\t********************************************\n"
<< "\t\t*
*\n"
<< "\t\t******欢迎使用江西理工大学课程管理系统******\n"
<< "\t\t********************************************\n"
<< "\t\t*
*\n"
<< "\t\t*
*\n"
<< "\t\t*
*\n"
<< "\t\t*
*\n"
<< "\t\t*
*\n"
<< "\t\t*
*\n"
<< "\t\t*
<< "\t\t*
*\n"
<< "\t\t********************************************\n";
0.退回到主菜单
(学生端):
1.信息浏览
2.信息查询
*\n"