typedef struct Student {
char id[12];
char name[20];
struct Student *next;
} Student;
void ensure_file_exists() {
FILE *fp = fopen("student.txt", "rb");
if (!fp) {
fp = fopen("student.txt", "wb+");
if (!fp) { perror("創建文件失敗"); exit(1); }
}
fclose(fp);
}
void add_student() {
FILE *fp = fopen("student.txt", "ab"); // 追加二進位
if (!fp) { perror("打開文件失敗"); return; }
Student stu;
printf("輸入學號: "); scanf("%11s", stu.id);
printf("輸入姓名: "); scanf("%19s", stu.name);
stu.next = NULL; // 文件中不存指針
fwrite(&stu, sizeof(Student), 1, fp);
fclose(fp);
printf("錄入成功\n");
}
Student *build_list_from_file() {
FILE *fp = fopen("student.txt", "rb");
if (!fp) return NULL;
Student *head = calloc(1, sizeof(Student)); // 哨兵頭節點,無數據
Student *tail = head;
Student tmp;
// 逐個讀取結構體塊
while (fread(&tmp, sizeof(Student), 1, fp) == 1) {
Student *node = malloc(sizeof(Student));
strcpy(node->id, tmp.id);
strcpy(node->name, tmp.name);
node->next = NULL;
tail->next = node; // 掛接到尾部
tail = node; // 移動尾指針
}
fclose(fp);
return head; // 返回哨兵頭
}
void print_list(Student *head) {
if (!head) { printf("鏈表為空\n"); return; }
int count = 0;
for (Student *p = head->next; p; p = p->next) {
printf("%3d: [%s] %s\n", ++count, p->id, p->name);
}
printf("共 %d 條記錄\n", count);
}
int main() {
ensure_file_exists();
int choice;
while (1) {
printf("\n1. 錄入學生\n2. 顯示所有\n0. 退出\n選擇: ");
scanf("%d", &choice);
if (choice == 1) add_student();
else if (choice == 2) {
Student *head = build_list_from_file();
print_list(head);
// 釋放鏈表
Student *p = head;
while (p) { Student *n = p->next; free(p); p = n; }
}
else if (choice == 0) break;
}
return 0;
}
| 項目 | 說明 |
|---|---|
| 模式 | `wb`/`ab`/`rb` 二進位模式,避免換行符轉換 |
| 結構體佈局 | 同一編譯器/平台讀寫安全;跨平台需序列化 |
| 指針字段 | **不寫入文件** (`next` 僅內存有效),讀取時重建 |
| 字符串 | 固定長度數組 `char id[12]` 直接寫入,含 `\0` |
| 對齊填充 | 結構體可能有填充位,整體 `fwrite` 保持一致 |
// 寫入
fprintf(fp, "%s,%s\n", stu.id, stu.name);
// 讀取
char line[64];
while (fgets(line, sizeof(line), fp)) {
Student tmp;
sscanf(line, "%11[^,],%19[^\n]", tmp.id, tmp.name);
// ... 建節點掛接
}
優點:人類可讀、跨平台、可用 Excel 打開。缺點:解析較慢、需處理逗號轉義。
「文件 ↔ 鏈表」是 C 語言經典持久化模式。核心模板:
// 讀取構建
head = calloc(1, sizeof(Node));
tail = head;
while (fread(&tmp, sizeof(Data), 1, fp) == 1) {
node = malloc(sizeof(Node));
copy_data(node, &tmp);
tail->next = node;
tail = node;
}
// 寫入同步
fp = fopen(file, "wb");
for (p = head->next; p; p = p->next) fwrite(p, sizeof(Data), 1, fp);
掌握哨兵頭節點、二進位塊讀寫、記憶體管理配對三要素,即可構建健壯的文件型鏈表應用。