基於控制台的學生信息管理系統,功能:查詢、錄入、修改。技術棧:C99、標準 I/O、動態記憶體、二進制文件存儲、模組化設計(頭文件 + 實現分離)。
main.c → 程式入口、選單循環 student.h → 資料結構、函式宣告、全域變數 student.c → 核心邏輯實現 stud.dat → 二進制數據文件 (持久化)
// student.h
#ifndef STUDENT_H
#define STUDENT_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char name[10];
int id;
int age;
char address[30];
} Student;
int menu(); // 顯示選單,回傳選項
void input_students(); // 錄入學生信息
void save_to_file(Student*); // 寫入二進制文件
void print_students(Student*, int); // 格式化輸出
void query_modify(int mode); // mode=0 查詢, mode=1 修改
void modify_student(Student*, int); // 修改指定學號記錄
void sort_students(Student*); // 按學號排序 (可選)
extern int student_count; // 全域學生數
#endif
// main.c
#include "student.h"
int main() {
int choice = menu();
while(choice != 1 && choice != 2 && choice != 3) {
printf("請重新輸入正確參數 (1-3):\n");
scanf("%d", &choice);
}
do {
switch(choice) {
case 1: query_modify(0); break; // 查詢
case 2: input_students(); break; // 錄入
case 3: query_modify(1); break; // 修改
}
printf("\n是否繼續其他操作?(Y/N): ");
char c = getchar(); // 吸收換行
c = getchar();
} while(c == 'Y' || c == 'y');
return 0;
}
// student.c 片段
void input_students() {
system("clear"); // Linux/macOS; Windows 用 "cls"
printf("學生信息錄入系統\n");
printf("請輸入學生人數: ");
scanf("%d", &student_count);
Student *students = (Student*)malloc(student_count * sizeof(Student));
if(!students) { printf("記憶體分配失敗!\n"); return; }
printf("依次輸入: 學號 姓名 年齡 地址\n");
for(int i = 0; i < student_count; i++) {
scanf("%d %s %d %s",
&students[i].id, students[i].name,
&students[i].age, students[i].address);
}
save_to_file(students);
free(students);
}
void save_to_file(Student *students) {
FILE *fp = fopen("stud.dat", "ab"); // 追加模式
if(!fp) {
fp = fopen("stud.dat", "wb"); // 首次創建
if(!fp) { perror("文件創建失敗"); exit(1); }
}
for(int i = 0; i < student_count; i++)
fwrite(&students[i], sizeof(Student), 1, fp);
fclose(fp);
printf("信息錄入完成!\n");
}
void query_modify(int mode) {
system("clear");
FILE *fp = fopen("stud.dat", "rb");
if(!fp) { printf("無數據文件\n"); return; }
// 先計算記錄數
Student tmp;
int count = 0;
while(fread(&tmp, sizeof(Student), 1, fp) == 1) count++;
rewind(fp);
Student *students = (Student*)malloc(count * sizeof(Student));
for(int i = 0; i < count; i++)
fread(&students[i], sizeof(Student), 1, fp);
fclose(fp);
print_students(students, count);
if(mode == 1) modify_student(students, count);
else free(students);
}
void modify_student(Student *students, int count) {
int target_id;
printf("輸入要修改的學號: ");
scanf("%d", &target_id);
for(int i = 0; i < count; i++) {
if(students[i].id == target_id) {
printf("輸入新信息: 學號 姓名 年齡 地址\n");
scanf("%d %s %d %s",
&students[i].id, students[i].name,
&students[i].age, students[i].address);
break;
}
}
// 全量覆寫文件
FILE *fp = fopen("stud.dat", "wb");
for(int i = 0; i < count; i++)
fwrite(&students[i], sizeof(Student), 1, fp);
fclose(fp);
free(students);
printf("修改成功!\n");
}
| 技術點 | 實現方式 | 注意事項 |
|---|---|---|
| 動態記憶體 | malloc/free 配對 | 檢查回傳值,用完即釋放 |
| 二進制文件 | fread/fwrite 結構體 | 結構體無指標成員,固定大小 |
| 文件模式 | "ab" 追加 / "wb" 覆寫 / "rb" 讀取 | 修改需全量覆寫 |
| 輸入緩衝 | getchar() 吸收換行 | scanf 留下換行干擾後續輸入 |
| 跨平台清屏 | system("clear"/"cls") | 教學用;生產用 ANSI 轉義序列 |
這個專案展示了 C 語言「小而美」的系統構建能力:無框架依賴、直接操作記憶體與文件、模組化清晰。適合初學者理解「資料結構 + 文件 I/O + 選單驅動」的經典應用架構。