hi,大家好,我是七仔。一个力争变得更优秀的七仔。
这是我刚注册后不久在csdn写的第一篇博客,注册csdn也是想让自己的大学生活学有所成,不希望毕业之后再来懊悔当初自己的不努力,写博客还是不是很熟悉,术语不是很专业,可能会给大家引起歧义,读起来可能会比较吃力,请大家多多担待,有说话不恰当的地方或代码说法有错误的地方,代码编写方面哪些可以完善的地方,请大家多多指出。初来乍到,请多关照。
本代码是用C语言来实现的学生成绩管理系统,代码编写有注释,编写程序方面我碰到的错误卡了我很多时间的地方我在代码里都有注释---写了很大一段:),话不多说,开整开整。
总体架构:有mian.c(程序的入口),menu.c(菜单文件),manange.c(各功能函数实现,如插入,删除,查找,输出,修改等),control.c(菜单与功能函数实现间的桥梁),login.c(登录模块),对应的有menu.h,manage.h,control.h,login.h。
menu.h
#ifndef __MENU_H__
#define __MENU_H__
int menu();
#endif
menu.c //菜单模块
#include<stdio.h>
#include"menu.h"
int menu(){
int choice;
printf("======================\n");
printf("=+ 学生成绩管理系统 +=\n");
printf("======================\n");
printf("=+ 1 添加记录 +=\n");
printf("=+ 2 显示记录 +=\n");
printf("=+ 3 修改记录 +=\n");
printf("=+ 4 删除记录 +=\n");
printf("=+ 5 查找记录 +=\n");
printf("=+ 6 排序记录 +=\n");
printf("=+ 7 保存记录 +=\n");
printf("=+ 8 打开记录 +=\n");
printf("=+ 0 退出系统 +=\n");
printf("======================\n");
printf("=+ 请选择 (0 - 8): ");
scanf("%d",&choice);
while(choice < 0 || choice >= 9){
printf("您的输入有误,请重输:");
scanf("%d",&choice);
}
return choice;
}
manage.h //用户可以定义自己文件的存放位置,文件的保存与打开如不需要该功能的话不用就OK的,没有什么关联性,只是文件有效保存后的话,(有效保存的意思是文件里面有数据,且正确可行)下次可以直接打开文件,就不需要自己去添加学生记录了。
#ifndef __MANAGE_H__
#define __MANAGE_H__
#define filename "e:\\sinfo.txt"
#define N 256 //最大学生数
typedef struct student_t{
char name[32];//姓名
char id[16];//学号
double mat;//高数成绩
double eng;//英语成绩
double sum;//总分
}student;
void add(student s[],int *n); //添加学生记录
void dis(student s[],int i); //输出第i个学生记录
void show(student s[],int n); //输出所有学生记录
void mod(student s[],int n); //修改学生记录
void del(student s[],int *n); //删除学生记录
void search(student s[],int n); //查找学生记录
void sort(student s[],int n); //排序学生记录
void save(student s[],int n); //保存文件
void load(student s[],int *n); //打开文件
#endif
manage.c//函数功能具体实现部分,这个系统核心部分了。
#include<stdio.h>
#include<string.h>
#include "manage.h"
//添加学生记录 因为添加学生记录会改变结构体数组元素个数 传地址 *n,
void add(student s[],int *n){
int i;
char num[16];//保存新的学号
char quit; //是否继续标志位
do{
printf("学号:");
scanf("%s",num);
for(i = 0;i < *n;i++){
if(strcmp(num,s[i].id) == 0){
printf("学号已存在!\n");
return;
}
}
i = *n;
strcpy(s[i].id,num);
printf("姓名:");
scanf("%s",&s[i].name);
printf("数学成绩:");
scanf("%lf",&s[i].mat);
printf("英语成绩:");
scanf("%lf",&s[i].eng);
s[i].sum = s[i].mat + s[i].eng;
(*n)++;
printf("添加成功!\n");
getchar();//清除键盘缓冲
printf("是否继续? (y / n) ");
scanf("%c",&quit);
}while(quit == 'y' || quit == 'Y');
}
//输出第i个学生记录
void dis(student s[],int i){
printf("%-5s%-5s%-5.1lf%-5.1lf%-5.1lf\n",s[i].id,s[i].name,s[i].mat,s[i].eng,s[i].sum);
}
//显示所有学生记录
void show(student s[],int n){
int i;
for(i = 0;i < n;i++){
printf("学号 姓名 数学 英语 总分\n");
printf("%-5s%-5s%-5.1lf%-5.1lf%-5.1lf\n",s[i].id,s[i].name,s[i].mat,s[i].eng,s[i].sum);
}
}
//修改学生记录
void mod(student s[],int n){
char sn[16];
int i;
char ch;
printf("要修改学生记录的学号为:");
scanf("%s",sn);
for(i = 0;i < n;i++){
if((strcmp(s[i].id,sn)) == 0) {
getchar();//清除键盘缓存
printf("找到此人!");
dis(s,i);
printf("是否修改?(y / n) ");
ch = getchar();
if(ch == 'y' or ch == 'y'){
printf("数学成绩:");
scanf("%lf",&s[i].mat);
printf("英语成绩: ");
scanf("%lf",&s[i].eng);
s[i].sum = s[i].mat + s[i].eng;
printf("修改成功!\n");
return;
}
else{
printf("用户取消!\n");
return;
}
}
}
printf("查无此人!\n");
}
//删除学生记录
void del(student s[],int *n){
char sn[16];
int i;
char ch;
printf("请输入学号:");
scanf("%s",sn);
for(i = 0;i < *n;i++){
if(strcmp(s[i].id,sn) == 0){
getchar();
printf("找到该学生记录 ");
dis(s,i);
printf("确认删除?(y / n)");
ch = getchar();
if(ch == 'y' or ch == 'Y'){
for(;i < *n;i++){
s[i] = s[i+1];
}
(*n)--;
printf("删除成功!\n");
return;
}
else{
printf("用户取消!\n");
return;
}
}
}
printf("查无此人!");
}
//查找学生记录
void search(student s[],int n){
int i;
char sn[16];
char name[16];
int ch;
double min,max;
int count = 0;
printf("==================\n");
printf("=+ 1 按学号查找 +=\n");
printf("=+ 2 按姓名查找 +=\n");
printf("=+ 3 按总分查找 +=\n");
printf("=+ 4 按高数查找 +=\n");
printf("=+ 5 按英语查找 +=\n");
printf("==================\n");
printf("=+ 请输入( 1 - 5 )");
scanf("%d",&ch);
switch(ch){
case 1:
printf("按学号查找\n");
printf("请输入学号:");
scanf("%s",sn);
for(i = 0;i < n;i++){
if(strcmp(s[i].id,sn) == 0){
printf("找到了!");
dis(s,i);
return;
}
}
printf("查无此人!\n");
break;
case 2:
printf("按姓名查找\n");
printf("请输入姓名:");
scanf("%s",name);
for(i = 0;i < n;i++){
if(strcmp(s[i].name,name) == 0){
printf("找到了!");
dis(s,i);
return;
}
}
printf("查无此人!\n");
break;
case 3:
printf("按总分段查找\n"); //按总分分数段进行查询,若要查一个具体的分数,如190,则上限和下限都设为190即可。下面的按英语和数学成绩查询也是同理
printf("请输入分数下限:");
scanf("%lf",&min);
printf("请输入分数上限: ");
scanf("%lf",&max);
for(i = 0;i < n;i++){
if(s[i].sum >= min && s[i].sum <= max){
dis(s,i);
count++;
}
}
if(count == 0) printf("查无此人!\n");
break;
case 4:
count = 0;
printf("按高数成绩段查找\n");
printf("请输入分数下限:");
scanf("%lf",&min);
printf("请输入分数上限: ");
scanf("%lf",&max);
for(i = 0;i < n;i++){
if(s[i].mat >= min && s[i].mat <= max){
dis(s,i);
count++;
}
}
if(count == 0) printf("查无此人!\n");
break;
case 5:
count = 0;
printf("按英语成绩段查找\n");
printf("请输入分数下限:");
scanf("%lf",&min);
printf("请输入分数上限: ");
scanf("%lf",&max);
for(i = 0;i < n;i++){
if(s[i].eng >= min && s[i].eng <= max){
dis(s,i);
count++;
}
}
if(count == 0) printf("查无此人!\n");
break;
}
}
//排序学生记录
void sort(student s[],int n){
student t;
int i,j;
int ch;
printf("==================\n");
printf("=+ 1 按总分升序排序 +=\n");
printf("=+ 2 按总分降序排序 +=\n");
printf("=+ 3 按数学升序排序 +=\n");
printf("=+ 4 按数学降序排序 +=\n");
printf("=+ 5 按英语升序排序 +=\n");
printf("=+ 6 按英语降序排序 +=\n");
printf("==================\n");
printf("=+ 请输入( 1 - 6 )");
scanf("%d",&ch);
switch(ch){
//冒泡排序
case 1:
printf("按总分升序排序\n");
for(i = 0;i < n-1;i++){
for(j = 0;j <n-i-1;j++){
if(s[j].sum > s[j+1].sum){
t = s[j];
s[j] = s[j+1];
s[j+1] = t;
}
}
}
printf("排序成功!\n");
break;
case 2:
printf("按总分降序排序\n");
for(i = 0;i < n-1;i++){
for(j = 0;j <n-i-1;j++){
if(s[j].sum < s[j+1].sum){
t = s[j];
s[j] = s[j+1];
s[j+1] = t;
}
}
}
printf("排序成功!\n");
break;
//直接插入排序
case 3:
printf("按数学成绩升序排序\n");
for(i = 1;i < n;i++){
j = i;
while(j > 0){
if(s[j].mat < s[j-1].mat){
t = s[j];
s[j] = s[j-1];
s[j-1] = t;
}
j--;
}
}
printf("排序成功!\n");
break;
case 4:
printf("按数学成绩降序排序\n");
for(i = 1;i < n;i++){
j = i;
while(j > 0){
if(s[j].mat > s[j-1].mat){
t = s[j];
s[j] = s[j-1];
s[j-1] = t;
}
j--;
}
}
printf("排序成功!\n");
break;
//选择排序
case 5:
printf("按英语成绩升序排序\n");
for(i = 0;i < n;i++){
for(j = i;j <n;j++){
if(s[i].eng > s[j].eng){
t = s[i];
s[i] = s[j];
s[j] = t;
}
}
}
printf("排序成功!\n");
break;
case 6:
printf("按英语成绩降序排序\n");
for(i = 0;i < n;i++){
for(j = i;j <n;j++){
if(s[i].eng < s[j].eng){
t = s[i];
s[i] = s[j];
s[j] = t;
}
}
}
printf("排序成功!\n");
break;
}
}
//保存文件
void save(student s[],int n){
FILE *fp;
int i;
if( (fp = fopen(filename,"w")) == NULL){
printf("以写方式打开文件失败!");
return;
}
for(i = 0;i < n;i++){
fprintf(fp,"%s %s %.1lf %.1lf %.1lf\n",s[i].id,s[i].name,s[i].mat,s[i].eng,s[i].sum);
}
fclose(fp);
printf("文件保存成功!\n");
}
//打开文件
void load(student s[],int *n){
FILE *fp;
int i = 0;
if ( (fp = fopen(filename,"r")) == NULL){
printf("以读方式打开文件失败!");
return;
}
/*文件不好控制结尾,如果不小心会有回车,空格之类的,输出结果会出错,会多出一行或一个字符,
因为这个学生成绩管理系统的特殊性,总分是可以通过其他科目分数相加而成的。
所以我们只需把前面的数据输到结构体数组中去,然后,%*数据类型->跳过一个该数据类型的大小,
但指针却跳到了结尾。所以第二轮循环的时候输出就不会错。*/
for(i = 0;!feof(fp);i++){
if((fscanf(fp,"%s %s %lf %lf %*lf",&s[i].id,&s[i].name,&s[i].mat,&s[i].eng))!=4)
break;
s[i].sum = s[i].mat + s[i].eng;
printf("%s %s %.1lf %.1lf %.1lf\n",s[i].id,s[i].name,s[i].mat,s[i].eng,s[i].sum);
}
*n = i;
fclose(fp);
printf("文件打开成功\n");
}
control.h
#ifndef __CONTROL_H__
#define __CONTROL_H__
void control();
#endif;
control.c //菜单模块和函数功能实现的桥梁
#include<stdio.h>
#include<stdlib.h>
#include "control.h"
#include "menu.h"
#include "manage.h"
void control(){
int n = 0;
int flag;
student stu[N];
system("title 学生成绩管理系统 authored by 七仔"); //起标题
system("mode con cols=55 lines=25"); //设置框框大小
system("color 3f");//设置前后景颜色
while(1){
flag = menu();
switch (flag){
case 0:
printf("谢谢使用,欢迎下次光临!");
break;
case 1:
add(stu,&n);
break;
case 2:
show(stu,n);
break;
case 3:
mod(stu,n);
break;
case 4:
del(stu,&n);
break;
case 5:
search(stu,n);
break;
case 6:
sort(stu,n);
break;
case 7:
save(stu,n);
break;
case 8:
load(stu,&n);
break;
}
if(flag == 0) break;
system("pause");
system("cls");
}
}
login.h
#ifndef __LOGIN_H__
#define __LOGIN_H__
#define userfile "e:\\userfile.txt"
typedef struct user_t{
char ac[16];//用户登录账号
char pwd[16];//用户登录密码
}user;
int login();
#endif
login.c //使用该系统的用户登录,如果不需要的话,可自行去掉该模块,再在main.c里面进行稍微的修改就好了。
#include <stdio.h>
#include <string.h>
#include "login.h"
int login(){
FILE *fp;
user str;
char ac[16],pwd[16];
int i;//输入次数
fp = fopen(userfile,"r");
printf("用户登录\n");
//输入次数,输入次数超过三次的话就
for(i = 0;i < 3;i++){
printf("请输入账号: ");
scanf("%s",ac);
printf("请输入密码:");
scanf("%s",pwd);
while(!feof(fp)){
fscanf(fp,"%s %s",&str.ac,&str.pwd);
if(strcmp(ac,str.ac) == 0 && strcmp(pwd,str.pwd) == 0){
return 1;
}
}
rewind(fp); //因为一次遍历过后,指针指到了最后面。要将指针放到开头才能进行下次遍历,否则结果会出错
printf("账号密码输入错误!\n");
}
return 0;
}
main.c
#include <stdio.h>
#include <stdlib.h>
#include "menu.h"
#include "manage.h"
#include "control.h"
#include "login.h"
int main(){
if(login() == 1){
printf("登录成功!\n");
system("pause");
system("cls");
control();
}
else printf("输入错误三次,请稍后再试\n");
}