学习完C语言的基本课程,很多老师都会布置一个大作业,让同学们编写出学生信息管理系统。学生信息管理系统可以用来管理班级学生,对学生信息(包括姓名、性别、年龄、成绩等)进行增加、删除、更改、查询等操作。
该系统主要有两种实现方案:第一种将学生信息直接保存在二进制文件中,当需要查询或者更新时,要能够使用文件操作函数精确定位学生信息;第二种使用数据结构中的链表,将学生信息暂时缓存在链表,如果有变化,才更新到文件。
本节我们以第一种方案为例,搭建起学生信息管理系统的框架,将前面几节的知识综合运用起来。
创建一个文件夹,命名为 StuInfo,并添加以下几个文件:
可以看到,我们将所有的头文件放在了 include 目录,将所有的源文件放在了 module 目录,而 main.c 作为主模块,直接放在了 StuInfo 目录。下面是对各个文件的说明:
程序主模块,执行入口,会调用其他模块中的函数。
该模块包含了程序的大部分代码,实现了对学生信息的增删改查操作。
包含了一些通用的函数,比如文件复制、获取文件大小、数据插入、数据删除等与文件操作有关的函数(在《C语言文件操作》一章已经对它们进行了实现),这些函数不仅可以用于当前项目,也可以不加修改地移植到其他项目,通用性很强,不妨将它们称为工具型函数。
定义了一些全局变量。比如文件指针 fp、学生总数、文件长度等。
配置文件,几乎都是宏定义,比如规定了学号的最大值、姓名的最大长度、成绩的最大值、文件路径等。
下面给出了每个文件包含的简略代码。由于本节仅仅是演示,所以下面的代码不完整,我们将在《C语言项目实践》中讲解学生信息管理系统的具体编码。
main.c 源码:
#include <stdio.h>
#include <stdlib.h>
#include "./include/config.h"
#include "./include/stu.h"
#include "./include/vars.h"
int main(){
init();
//addStuInfo();
//deleteStuInfo();
//findStuByID();
//findStuByName();
fclose(fp);
return 0;
}
stu.c 源码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../include/config.h"
#include "../include/stu.h"
#include "../include/tools.h"
#include "../include/vars.h"
//初始化
void init(){
//打开文件
if( (fp=fopen(FILENAME, "rb+")) == NULL && (fp=fopen(FILENAME, "wb+")) == NULL ){
pause("Error on open %s file!", FILENAME);
exit(EXIT_FAILURE);
}
//获取文件长度
fileSize = getFileSize(fp);
}
//添加学生信息
void addStuInfo(){
//finsert(fp, nPreEleCount*stuSize, &stu, stuSize);
pause("提示:添加成功!按任意键返回...");
}
//删除学生信息
void deleteStuInfo(){
//fdelete(fp, index*stuSize, stuSize);
pause("提示:删除成功,按任意键返回...");
}
//修改学生信息
void alterStuInfo(){
//fwrite(&stu, stuSize, 1, fp);
pause("提示:修改成功,按任意键返回...");
}
//根据学号查询学生信息
void findStuByID(){
pause("错误:该学生信息不存在,查询失败!按任意键返回...");
}
//根据姓名查询学生信息
void findStuByName(){
pause("错误:没有查询到相关记录!按任意键返回...");
}
//根据成绩查询学生信息
void findStuByScores(){
pause("错误:没有查询到相关记录!按任意键返回...");
}
//显示所有学生信息
void showAllStu(){
pause("\n共有%d条学生信息,按任意键返回...", n);
}
stu.h 源码:
#ifndef _STU_H
#define _STU_H
//学生信息结构体
typedef struct _STU{
int id; //学号
char name[20]; //姓名
char sex[4]; //性别
int age; //年龄
float math; //数学成绩
float cn; //语文成绩
float en; //英语成绩
}STU;
//初始化
extern void init();
//学生信息增删改查
extern void addStuInfo();
extern void deleteStuInfo();
extern void alterStuInfo();
extern void findStuByID();
extern void findStuByName();
extern void findStuByScores();
extern void showAllStu();
#endif
tools.c 源码:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <conio.h>
#include <stdarg.h>
//获取文件大小(以字节计)
long getFileSize(FILE *fp){
long fsize;
//TODO:
return fsize;
}
//文件复制函数
long fcopy(FILE *fSource, long offsetSource, long len, FILE *fTarget, long offsetTarget){
long nBytes = 0; //总共复制了多少个字节
//TODO:
return nBytes;
}
//向文件中插入内容
int finsert(FILE *fp, long offset, void *buffer, int len){
//TODO:
return 0;
}
//从文件中删除内容
int fdelete(FILE *fp, long offset, int len){
//TODO:
return 0;
}
//暂停程序
void pause(const char *str, ...){
va_list vl;
char buf[500] = {0};
va_start(vl, str);
vsnprintf(buf, 500, str, vl);
va_end(vl);
printf(buf);
getch();
printf("\n");
}
tools.h 源码:
#ifndef _TOOLS_H
#define _TOOLS_H
extern long getFileSize(FILE *fp); //获取文件大小
extern long fcopy(FILE *fSource, long offsetSource, long len, FILE *fTarget, long offsetTarget); //文件内容复制
extern int finsert(FILE *fp, long offset, void *buffer, int len); //向文件中插入数据
extern int fdelete(FILE *fp, long offset, int len); //删除文件内容
extern void pause(const char *str, ...); //暂停程序
#endif
vars.c 源码:
FILE *fp = NULL; //文件指针
int stuCount = 0; //总共有多少条学生信息
long fileSize = 0; //文件长度(占用的字节数)
vars.h 源码:
#ifndef _VARS_H
#define _VARS_H
extern FILE *fp;
extern int stuCount;
extern long fileSize;
#endif
config.h 源码:
#ifndef _CONFIG_H
#define _CONFIG_H
#define FILENAME "stu.data" //保存学生信息的文件名称(含路径)
#define MAX_STU_ID 99 //学号的最大值
#define MAX_STU_NAME 10 //姓名的最大长度
#define MAX_STU_AGE 100 //年龄的最大值
#define MAX_STU_MATH 150 //数学成绩的最大值
#define MAX_STU_EN 150 //英语成绩的最大值
#define MAX_STU_CN 150 //语文成绩的最大值
#endif