數據結構設計
typedef struct Worker {
int id;
char name[20];
char sex[4];
int age;
char edu[20];
double salary;
char addr[50];
char phone[15];
struct Worker *next;
} Worker;
Worker *head = NULL; // 單向鏈表頭指標
核心功能模組
1. 讀取文件初始化
void load_from_file(const char *filename) {
FILE *fp = fopen(filename, "rb");
if (!fp) return;
Worker tmp;
while (fread(&tmp, sizeof(Worker), 1, fp) == 1) {
Worker *n = malloc(sizeof(Worker));
*n = tmp; n->next = NULL;
// 尾插法
if (!head) head = n;
else { Worker *p = head; while (p->next) p = p->next; p->next = n; }
}
fclose(fp);
}
2. 保存文件
void save_to_file(const char *filename) {
FILE *fp = fopen(filename, "wb");
if (!fp) return;
for (Worker *p = head; p; p = p->next)
fwrite(p, sizeof(Worker), 1, fp);
fclose(fp);
}
3. 新增 (ID 唯一檢查)
int add_worker() {
Worker *n = malloc(sizeof(Worker));
printf("ID: "); scanf("%d", &n->id);
for (Worker *p = head; p; p = p->next)
if (p->id == n->id) { free(n); puts("ID 已存在"); return 0; }
printf("姓名: "); scanf("%19s", n->name);
printf("性別: "); scanf("%3s", n->sex);
printf("年齡: "); scanf("%d", &n->age);
printf("學歷: "); scanf("%19s", n->edu);
printf("工資: "); scanf("%lf", &n->salary);
printf("地址: "); scanf("%49s", n->addr);
printf("電話: "); scanf("%14s", n->phone);
n->next = head; head = n; // 頭插法
puts("添加成功");
return 1;
}
4. 遍歷顯示
void list_workers() {
printf("%-6s %-10s %-4s %-4s %-10s %-10s %-20s %-15s\n",
"ID", "姓名", "性別", "年齡", "學歷", "工資", "地址", "電話");
for (Worker *p = head; p; p = p->next) {
printf("%-6d %-10s %-4s %-4d %-10s %-10.2f %-20s %-15s\n",
p->id, p->name, p->sex, p->age, p->edu, p->salary, p->addr, p->phone);
}
}
5. 查詢 (ID/姓名)
Worker* find_by_id(int id) {
for (Worker *p = head; p; p = p->next)
if (p->id == id) return p;
return NULL;
}
Worker* find_by_name(const char *name) {
for (Worker *p = head; p; p = p->next)
if (strcmp(p->name, name) == 0) return p;
return NULL;
}
6. 刪除 (按 ID)
int delete_by_id(int id) {
Worker **pp = &head; // 指向指標的指標,統一處理頭節點
while (*pp) {
if ((*pp)->id == id) {
Worker *tmp = *pp;
*pp = (*pp)->next;
free(tmp);
puts("刪除成功");
return 1;
}
pp = &(*pp)->next;
}
puts("未找到該 ID");
return 0;
}
主選單循環
int main() {
load_from_file("workers.dat");
int choice;
while (1) {
puts("\n1.添加 2.列表 3.ID查詢 4.姓名查詢 5.刪除 0.退出");
printf("選擇: ");
if (scanf("%d", &choice) != 1) break;
switch (choice) {
case 1: add_worker(); break;
case 2: list_workers(); break;
case 3: { int id; scanf("%d", &id); Worker *p=find_by_id(id); if(p) printf("找到: %s\n", p->name); else puts("無"); } break;
case 4: { char name[20]; scanf("%19s", name); Worker *p=find_by_name(name); if(p) printf("找到: ID=%d\n", p->id); else puts("無"); } break;
case 5: { int id; scanf("%d", &id); delete_by_id(id); } break;
case 0: save_to_file("workers.dat"); puts("數據已保存,再見!"); return 0;
default: puts("無效選項");
}
}
return 0;
}
進階擴展建議
- **雙向鏈表** 支援反向遍歷。
- **索引優化**:ID 哈希表 / 姓名 Trie 樹,大數據量下 O(1)/O(L) 查詢。
- **SQLite 嵌入式資料庫**:替代手寫文件持久化,支援 SQL 查詢、事務、並發。
- **圖形界面**:GTK / Qt / Win32 API 封裝上層邏輯。