?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)。
要在調試停止時自動關閉控制臺,請啟用“工具”->“選項”->“調試”->“調試停止時自動關閉控制臺”。
按任意鍵關閉此窗口. . .
源代碼如下:?
雙葉/學生信息表
注:該代碼是本人自己所寫,可能不夠好,不夠簡便,歡迎大家指出我的不足之處。如果遇見看不懂的地方,可以在評論區打出來,進行討論,或者聯系我。上述內容全是我自己理解的,如果你有別的想法,或者認為我的理解不對,歡迎指出!!!如果可以,可以點一個免費的贊支持一下嗎?謝謝各位彥祖亦菲!!!!!??