1.首先是头文件:
//student.h
//头文件//防止头文件被重复包含#pragma once//宏定义符号常量,方便维护和修改
#define ID_MAX 20
#define NAME_MAX 20
#define AGE_MAX 5
#define SEX_MAX 5
#define CLA_MAX 20
//定义初始最大容量
#define MAX 1//定义结构体学生
struct Student
{//定义学生信息char id[ID_MAX];char name[NAME_MAX];char age[AGE_MAX];char sex[SEX_MAX];char cla[CLA_MAX];
};//定义结构体学生信息本
struct Book
{//数据struct Student* data;//当前学生个数int sz;//当前容量int capacity;
};//项目函数声明
void menu();
void InitBook(struct Book* stu);
void ReadBook(struct Book* stu);
void WriteBook(struct Book* stu);
void CheckBook(struct Book* stu);
void clear_screen();
void AddBook(struct Book* stu);
void ShowBook(struct Book* stu);
void CheckCapacity(struct Book* stu);
void ExitBook(struct Book* stu);
void ClearBook(struct Book* stu);
2. 然后是功能函数student.c文件
//student.c
//函数体文件//调用头文件
#include "student.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>//定义函数体//定义清屏函数
//清屏操作
void clear_screen() {//判断是否为Windows系统
#ifdef _WIN32system("cls");//其他系统
#elsesystem("clear");
#endif
}//菜单函数
void menu()
{printf("*********************************************\n");printf("******** 1.添加 2.删除 **************\n");printf("******** 3.查询 4.修改 **************\n");printf("******** 5.查看 6.排序 **************\n");printf("******** 7.清空 0.退出 **************\n");printf("*********************************************\n");
}//检查容量是否溢出
void CheckCapacity(struct Book* stu) {if (stu->sz == 0) {printf("当前学生信息本为空!\n");}printf("当前容量为:%d\n", stu->capacity);printf("当前学生为:%d\n", stu->sz);
}//检查容量函数
void CheckBook(struct Book* stu) {//检查是否溢出if (stu->sz == stu->capacity) {printf("容量已满!开始扩容!\n");int newcapacity = (stu->capacity == 0) ? MAX : stu->capacity * 2;struct Student* cap = (struct Student*)realloc(stu->data, newcapacity * sizeof(struct Student));if (cap == NULL) {printf("扩容失败!\n");return;}stu->data = cap;stu->capacity = newcapacity;printf("扩容成功!\n");}
}//初始化学生信息函数
void InitBook(struct Book* stu) {//初始化为0或空stu->sz = 0;stu->data = NULL;stu->capacity = 0;//读取文件信息ReadBook(stu);//如果文件没有数据,初始化空间内存if (stu->sz == 0) {stu->data = (struct Student*)calloc(MAX, sizeof(struct Student));if (stu->data == NULL) {printf("初始化空间内存失败!\n");return;}stu->capacity = MAX;}
}
//读取文件函数
void ReadBook(struct Book* stu) {//打开文件FILE* fp = fopen("Studentbook.txt", "rb");if (fp == NULL) {return;}//定义一个临时结构体struct Student tmp;while (fread(&tmp,sizeof(struct Student),1,fp)) {//检查容量是否溢出CheckBook(stu);stu->data[stu->sz] = tmp;stu->sz++;CheckCapacity(stu);}fclose(fp);fp = NULL;
}//写入文件
void WriteBook(struct Book* stu) {FILE* fp = fopen("Studentbook.txt", "wb");if (fp == NULL) {printf("读取文件失败!\n");return;}for (int i = 0; i < stu->sz; i++) {fwrite((stu->data + i), sizeof(struct Student), 1, fp);}fclose(fp);fp = NULL;
}//添加学生信息
void AddBook(struct Book* stu) {CheckBook(stu);printf("请输入学号:");scanf("%s", stu->data[stu->sz].id);printf("请输入姓名:");scanf("%s", stu->data[stu->sz].name);printf("请输入年龄:");scanf("%s", stu->data[stu->sz].age);printf("请输入性别:");scanf("%s", stu->data[stu->sz].sex);printf("请输入班级:");scanf("%s", stu->data[stu->sz].cla);printf("添加成功!\n");(stu->sz)++;CheckCapacity(stu);
}//查询学生信息本
void ShowBook(struct Book* stu) {CheckCapacity(stu);printf("%-19s\t%-15s\t%-5s\t%-8s\t%-30s\n", "学号","姓名", "年龄", "性别", "班级");for (int i = 0; i < stu->sz; i++) {printf("%-19s\t%-15s\t%-5s\t%-8s\t%-30s\n", stu->data[i].id,stu->data[i].name,stu->data[i].age, stu->data[i].sex, stu->data[i].cla);}
}//退出学生信息本函数
void ExitBook(struct Book* stu) {WriteBook(stu);printf("退出成功!欢迎下次使用!\n");
}//释放空间函数
void ClearBook(struct Book* stu) {free(stu->data);stu->data = NULL;stu->sz = 0;stu->capacity = 0;
}
3.最后是主程序test.c文件:
//test.c
//测试文件//调用头文件
#include "student.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>enum Option
{EXIT,//0,对应退出通讯录ADD,//1,对应添加联系人DEL,//2,对应删除联系人SEARCH,//3,对应查询联系人MODIFY,//4,对应修改联系人SHOW,//5,对应查看通讯录SORT,//6,对应排序通讯录CLEAR,//7,对应清空通讯录
};//程序主函数
int main() {//定义结构体变量struct Book stu;//初始化学生信息InitBook(&stu);int input = 0;int menu_0 = 0;do {//打印菜单while (1) {printf("************按1继续************\n");if (scanf("%d", &menu_0) != 1 && menu_0 != 1) {printf("输入不合法,请按1继续\n");return 1;}clear_screen();if (menu_0 == 1){menu();break;}}printf("请选择对应模式(0-7):\n");if (scanf("%d", &input) != 1 || input < 0 || input > 7) {printf("输入不合法,请输入整数0-7\n");return 1;}switch (input){case ADD: {clear_screen();AddBook(&stu);break;}case SHOW: {clear_screen();ShowBook(&stu);break;}case EXIT: {clear_screen();ExitBook(&stu);break;}default:break;}} while (input);ClearBook(&stu);return 0;
}
整个项目只有三个文件,头文件和两个源代码
下面是部分重要代码解析:
代码结构与核心知识点
1. 头文件
student.h
知识点:头文件保护、宏定义、结构体声明、函数原型。
#pragma once // 防止重复包含 #define ID_MAX 20 // 宏定义常量,便于维护struct Student { // 学生信息结构体char id[ID_MAX]; // 字符串存储,避免溢出// ...其他字段 };struct Book { // 学生信息管理结构体struct Student* data; // 动态数组指针int sz; // 当前学生数量int capacity; // 当前容量 };void InitBook(struct Book* stu); // 函数原型声明 // ...其他函数声明2. 核心功能文件
student.c
(1) 动态内存管理
知识点:
realloc
扩容、calloc
初始化。void CheckBook(struct Book* stu) {if (stu->sz == stu->capacity) {int newcapacity = (stu->capacity == 0) ? MAX : stu->capacity * 2; // 初始容量为 MAX=1struct Student* cap = realloc(stu->data, newcapacity * sizeof(struct Student)); // 动态扩容// ...错误处理} }(2) 文件读写
知识点:二进制文件操作(
fread
/fwrite
)。void ReadBook(struct Book* stu) {FILE* fp = fopen("Studentbook.txt", "rb"); // 二进制读模式while (fread(&tmp, sizeof(struct Student), 1, fp) { // 逐条读取数据CheckBook(stu); // 确保内存足够stu->data[stu->sz] = tmp; // 存储到动态数组stu->sz++;}// ...关闭文件 }void WriteBook(struct Book* stu) {FILE* fp = fopen("Studentbook.txt", "wb"); // 二进制写模式for (int i = 0; i < stu->sz; i++) {fwrite(&stu->data[i], sizeof(struct Student), 1, fp); // 逐条写入}// ...关闭文件 }(3) 用户交互
知识点:控制台输入、格式化输出。
void AddBook(struct Book* stu) {CheckBook(stu); // 检查容量scanf("%s", stu->data[stu->sz].id); // 输入学号(未限制长度,有溢出风险!)// ...其他输入stu->sz++; // 更新学生数量 }void ShowBook(struct Book* stu) {printf("%-19s\t...\n", "学号"); // 格式化对齐输出for (int i = 0; i < stu->sz; i++) {printf("%-19s\t...\n", stu->data[i].id, ...); // 显示所有学生} }3. 主程序
test.c
知识点:枚举类型、菜单驱动、循环控制。
enum Option { EXIT, ADD, DEL, ... }; // 用枚举提高可读性int main() {struct Book stu;InitBook(&stu); // 初始化do {menu(); // 打印菜单scanf("%d", &input); // 读取用户选项switch(input) {case ADD: AddBook(&stu); break; // 调用对应功能// ...其他选项}} while (input != EXIT);ClearBook(&stu); // 释放内存return 0; }
现在只做了3个功能,添加,查看,退出
后续将会继续完善和更新,代码部分运行结果如下:
容量已满!开始扩容!
扩容成功!
请输入学号:232
请输入姓名:李四
请输入年龄:13
请输入性别:女
请输入班级:C语言3班
添加成功!
当前容量为:4
当前学生为:3
************按1继续************
当前容量为:4
当前学生为:3
学号 姓名 年龄 性别 班级
1 1 1 1 1
231 张三 12 男 C语言2班
232 李四 13 女 C语言3班
************按1继续************
退出成功!欢迎下次使用!E:\Study\VS\VS Project\XIANGMU\1\StudentBook\x64\Debug\StudentBook.exe (进程 24368)已退出,代码为 0 (0x0)。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
源代码如下:
双叶/学生信息表
注:该代码是本人自己所写,可能不够好,不够简便,欢迎大家指出我的不足之处。如果遇见看不懂的地方,可以在评论区打出来,进行讨论,或者联系我。上述内容全是我自己理解的,如果你有别的想法,或者认为我的理解不对,欢迎指出!!!如果可以,可以点一个免费的赞支持一下吗?谢谢各位彦祖亦菲!!!!!