主函数,管理系统入口——StuManageMain.cpp
/*
这是学生管理系统入口
g++ -g ManageStuSys.cpp StuManageMain.cpp -I ../inc -o ../bin/StuManageSys
*/
#include <iostream>
#include "../inc/ManageStuSys.h"
using namespace std;
int main(){
char name[20],id[20],Grade[20],Class[20];
double socer = 0.0;
STU *head = (STU*)NodeInit();
STU *NewNode = (STU*)NodeInit();
NewNode->stuInfo[0] = NewNode->stuName;
NewNode->stuInfo[1] = NewNode->stuID;
NewNode->stuInfo[2] = NewNode->stuGrade;
NewNode->stuInfo[3] = NewNode->stuClass;
cout<<"┏━━━━━━━━┓"<<endl;
cout<<"┃学生信息管理程序┃"<<endl;
cout<<"┃ 【1】 添加学生信息 ┃"<<endl;
cout<<"┃ 【2】 修改学生成绩 ┃"<<endl;
cout<<"┃ 【3】 查询学生信息 ┃"<<endl;
cout<<"┃ 【4】 查看学生排名 ┃"<<endl;
cout<<"┃ 【5】 删除学生信息 ┃"<<endl;
cout<<"┃ 【6】 功能开发中.. ┃"<<endl;
cout<<"┃ 【7】 功能开发中.. ┃"<<endl;
cout<<"┃ 【q】 退出 ┃"<<endl;
cout<<"┗━━━━━━━━┛"<<endl;
cout<<" *****请输入0~7:";
char MenuNumber;
while(true){
cout <<"请输入指令:";
cin >> MenuNumber;
switch (MenuNumber)
{
case 'q':
cout <<"*****即将退出系统*****"<< endl;
exitPrecent();
free(head);
free(NewNode);
exit(0);
case '1':
cout <<"*****请添加添加学生信息*****"<< endl;
cout <<"*****格式:姓名,学号,年级,班级,总成绩*****"<< endl;
cin >> NewNode->stuName >> NewNode->stuID >> NewNode->stuGrade
>> NewNode->stuClass >> NewNode->stuScore;
// if(NewNode->stuScore){
// cout <<"成绩输入有误请重新输入"<<endl;
// break;
// }
addStuInfo(head, NewNode->stuInfo, NewNode->stuScore);
printNode(head);
saveStudInfo(NewNode);
break;
case '2':
cout <<"*****请输入修改的学生的学号、总成绩*****"<< endl;
cout <<"*****格式:学号,总成绩 *****"<< endl;
cin >> id >> socer;
modifyStuSocre(head,id,socer);
break;
case '3':
cout <<"*****请输入查询的学生姓名和学号*****"<< endl;
cout <<"*****格式:姓名,学号 *****"<< endl;
cin >> name >> id;
serachStuInfo(head,name,id);
break;
case '4':
cout <<"*****你现在正在查看学生成绩排名*****"<< endl;
getStuQueue(head);
break;
case '5':
cout <<"*****请输入删除的学生姓名和学号*****"<< endl;
cout <<"*****格式:姓名,学号 *****"<< endl;
cin >> name >> id;
deleteStuInfo(head,name,id);
break;
case '6':
cout <<"*****功能开发中*****"<< endl;
break;
case '7':
cout <<"*****功能开发中*****"<< endl;
break;
case '8':
cout <<"*****功能开发中*****"<< endl;
break;
default:
cout <<"您的输入有误,请重新输入"<< endl;
break;
}
}
return 0;
}
学生数据结构——ManageStuSys.h
#ifndef _HManageStuSys
#define _HManageStuSys
#pragma once
// define student struct
typedef struct STUNODE
{
char stuName[20];
char stuID[20];
char stuGrade[20];
char stuClass[20];
char *stuInfo[4] = {stuName,stuID,stuGrade,stuClass};
double stuScore;
STUNODE *next;
}STU;
void* NodeInit();
void printNode(STU *);
void exitPrecent();//显示退出系统百分比
void addStuInfo(STU *, char *[] , double);
void saveStudInfo(STU *);//存储学生信息
void modifyStuSocre(STU *,char [],double);//修改学生信息
bool serachStuInfo(STU *,char [],char []);//查询学生信息
void getStuQueue(STU *);//将学生排序
void deleteStuInfo(STU *,char [],char []);//删除学生信息
void* getInfoFromFile(const char*);
#endif
函数实现方法——ManageStuSys.cpp
/*
学生管理系统的一些函数实现
*/
#include <iostream>
#include <string>
#include <Windows.h>
#include <fstream>
#include "../inc/ManageStuSys.h"
void* NodeInit(){
STU *New;
New = (STU*)malloc(sizeof(STU));
New->next = NULL;
return New;
}
//显示所有成绩
void printNode(STU *New){
STU* Temp = New; // 从头指针开始
while(Temp->next){
std::cout <<"姓名:"<< Temp->next->stuName
<< "\t学号:"<< Temp->next->stuID
<< "\t年级:"<<Temp->next->stuGrade
<< "\t班级:"<<Temp->next->stuClass
<<"\t总成绩:"<< Temp->next->stuScore << std::endl;
Temp = Temp->next;
}
}
void exitPrecent(){
int i = 0;
printf("正在退出系统...\n");
while(1){
// for(int i =0 ;i<101;i+=10){
for(int j = 0 ;j <i;j+=10){
printf("*");
}
for(int n = 0; n<10-i/10;n++){
printf("=");
}
if(i<101){
Sleep(50);
printf("\r%d%%",i);
}
else
{
printf("\n已退出系统");
break;
}
i+=10;
}
}
// 添加学生
void addStuInfo(STU *New, char *stuInfo[], double stuScore){
STU *Temp = (STU*)NodeInit();
STU *endNode = New;
strcpy(Temp->stuName, stuInfo[0]);
strcpy(Temp->stuID, stuInfo[1]);
strcpy(Temp->stuGrade, stuInfo[2]);
strcpy(Temp->stuClass, stuInfo[3]);
Temp->stuScore = stuScore;
// 使用尾节点插入,先找尾节点,在尾节点之后插入
while(endNode->next){
endNode = endNode->next;
}
Temp->next = endNode->next;
endNode->next = Temp;
// free(Temp);
}
// 保存学生信息到文件
void saveStudInfo(STU *SaveNode){
std::ofstream out;
char str[100];
out.open("./stuinfo.txt",std::ofstream::app);
if(out.is_open()){
for(int i = 0;i < 4;i++){
strcpy(str, SaveNode->stuInfo[i]);
// std::cout << New->stuInfo[0] <<std::endl;
out << str;
if(i < 4)out << ",";
}
out << SaveNode->stuScore;
out << "\n";
}else{
std::cout <<"File Error"<<std::endl;
}
out.close();
}
// 修改学生成绩
void modifyStuSocre(STU *Temp, char id[], double socer){
STU *New = Temp;
while(New){
if(strcmp(New->stuID,id) == 0){
New->stuScore = socer;
std::cout <<"成绩已修改"<< std::endl;
std::cout <<"姓名:"<< New->stuName
<< "\t学号:"<< New->stuID
<< "\t年级:"<< New->stuGrade
<< "\t班级:"<< New->stuClass
<<"\t总成绩:"<< New->stuScore << std::endl;
break;
}
New = New->next;
if(New == NULL){
std::cout <<"学生不存在,请确认后重新输入"<<std::endl;
break;
}
}
}
// 查询学生信息
bool serachStuInfo(STU *Temp,char name[],char id[]){
STU *New = Temp;
bool flag = false;
while(New){
if(strcmp(New->stuName,name) == 0 && strcmp(New->stuID,id) == 0)
{
std::cout <<"姓名:"<< New->stuName
<< "\t学号:"<< New->stuID
<< "\t年级:"<< New->stuGrade
<< "\t班级:"<< New->stuClass
<<"\t总成绩:"<< New->stuScore << std::endl;
break;
}
New = New->next;
if(New == NULL){
flag = true;
std::cout <<"学生不存在,请确认后重新输入"<<std::endl;
break;
}
}
return flag;
}
// 删除学生信息
void deleteStuInfo(STU *TempNode,char name[],char id[]){
STU *New = TempNode;
STU *Temp = (STU*)malloc(sizeof(STU));
if(serachStuInfo(New,name,id)){
std::cout <<"学生不存在,请确认后重新输入"<<std::endl;
return;
}
while(New->next){
if(strcmp(New->next->stuName,name) == 0 && strcmp(New->next->stuID,id) == 0)
{
Temp->next = New->next->next;
New->next = Temp->next;
std::cout <<"学生信息已删除"<< std::endl;
break;
}
New = New->next;
}
free(Temp);
}
//根据成绩对学生排序,参数是头指针,从大到小排
void getStuQueue(STU *New){
STU *oriNode = New->next;
STU *copyNode = New;
int n = 0;
while(oriNode){
n++;
oriNode = oriNode->next;
}
free(oriNode);
//作为一个临时量
STU* test = New;
STU * p = (STU *)malloc(sizeof(STU));
STU * p1 = (STU *)malloc(sizeof(STU));
STU *temp = (STU *)malloc(sizeof(STU));
//如果链表为空直接返回
if (New->next == NULL)return;
New = New->next;//指向头指针后的头节点
for (int i = 0; i < n - 1; i++) {
test = New;//指定一个最大值
for (int j = 0; j < n - i - 1; j++) {
//得到两个值
p = test;
p1 = test->next;
//如果前面的那个比后面的那个大,就交换它们之间的是数据域
if (p->stuScore < p1->stuScore) {
//先将大的值的数据给临时值
temp->stuScore = p1->stuScore;
strcpy(temp->stuName,p1->stuName);
strcpy(temp->stuID,p1->stuID);
strcpy(temp->stuGrade,p1->stuGrade);
strcpy(temp->stuClass,p1->stuClass);
// 将大的放在前面
p1->stuScore = p->stuScore;
strcpy(p1->stuName,p->stuName);
strcpy(p1->stuID,p->stuID);
strcpy(p1->stuGrade,p->stuGrade);
strcpy(p1->stuClass,p->stuClass);
//将临时值放在后面
p->stuScore = temp->stuScore;
strcpy(p->stuName,temp->stuName);
strcpy(p->stuID,temp->stuID);
strcpy(p->stuGrade,temp->stuGrade);
strcpy(p->stuClass,temp->stuClass);
}
test = test->next;
}
}
printNode(copyNode);
free(temp);
}
使用make编译
Makefile写法
# 源码Path
PSRC = ./src/ManageStuSys.cpp ./src/StuManageMain.cpp
# 依赖头文件目录
INC = ./inc
# 生成的目标文件, 预处理、编译、汇编、链接
SRC = ManageStuSys.ii ManageStuSys.s ManageStuSys.o ManageStuSys.exe
BIN = ./bin
all : $(SRC) directToExe clean
# $(filter 指定生成的文件, 生成的文件集合),从生成的文件集合中筛选要生成的文件
# %.o: %.i : 前面是生成的文件,后面是依赖的文件
# $< 当前目标文件的第一个依赖文件
# $^ 当前目标文件的所有依赖文件
# % 代表当前生成目标的 文件名
# $@ 代表目标文件
# 预处理 -E
# 生成.i 预处理,预处理将源码中的 宏展开、头文件复制进来
$(filter %.ii, $(SRC)) : %.ii: ./src/%.cpp
pwd
echo Preprocessing Begin
g++ -E $< -o $(BIN)/$@
echo Preprocessing product .ii
# 编译 -S 依赖.i文件
# 生成.s
$(filter %.s, $(SRC)) : %.s: $(BIN)/%.ii
echo Compile Begin
g++ -S $< -o $(BIN)/$@
echo Compile product .s
# 汇编 -C 依赖.s文件
# 生成.o
$(filter %.o, $(SRC)) : %.o: $(BIN)/%.s
echo Assembly Begin
g++ -c $< -o $(BIN)/$@
# 手动生成.o文件,也可以在生成的目标文件中指定
g++ -c ./src/StuManageMain.cpp -o $(BIN)/StuManageMain.o
echo Assembly product .o
# 链接
# 生成exe
$(filter %.exe, $(SRC)) : %.exe: $(BIN)/%.o
echo Link Begin
g++ $< $(BIN)/StuManageMain.o -I $(INC) -o $(BIN)/StuManageSys
echo Link product .exe
# 直接生成exe
directToExe : $(PSRC)
g++ $(PSRC) -I $(INC) -o $(BIN)/$@
echo Compile End
clean :
# -rm -rf $(BIN)/*.*
echo allfile Done
Makefile展开
pwd
/h/CWorkSpace/GCCBuild/ManageSystem_NodeLink
echo Preprocessing Begin
Preprocessing Begin
g++ -E src/ManageStuSys.cpp -o ./bin/ManageStuSys.ii
echo Preprocessing product .ii
Preprocessing product .ii
echo Compile Begin
Compile Begin
g++ -S bin/ManageStuSys.ii -o ./bin/ManageStuSys.s
echo Compile product .s
Compile product .s
echo Assembly Begin
Assembly Begin
g++ -c bin/ManageStuSys.s -o ./bin/ManageStuSys.o
# 手动生成.o文件,也可以在生成的目标文件中指定
g++ -c ./src/StuManageMain.cpp -o ./bin/StuManageMain.o
echo Assembly product .o
Assembly product .o
echo Link Begin
Link Begin
g++ bin/ManageStuSys.o ./bin/StuManageMain.o -I ./inc -o ./bin/StuManageSys
echo Link product .exe
Link product .exe
g++ ./src/ManageStuSys.cpp ./src/StuManageMain.cpp -I ./inc -o ./bin/directToExe
echo Compile End
Compile End
# -rm -rf ./bin/*.*
echo allfile Done
allfile Done
生成exe
可直接使用下面命令直接生成exe
g++ -g ManageStuSys.cpp StuManageMain.cpp -I ../inc -o ../bin/StuManageSys