大二伊始,為鞏固大一 C 語言知識並預習 C++,我設計了一個「銷售管理系統」,綜合運用**結構體、指針、鏈表、文件讀寫、模塊化函數設計**,實現商品信息的增刪改查與持久化存儲。
Load_LinkList() 讀取二進制文件重建鏈表,Save_LinkList() 將鏈表寫入文件;while(1) + switch(getch()) 實現交互式控制台菜單。typedef struct Commodity {
int id; // 商品編號(頭結點用於統計總數)
char name[20]; // 名稱
double price; // 單價
int count; // 數量
double sum; // 總價(price * count,頭結點存總金額)
struct Commodity *next;
} *LinkList, LNode;
void Creat_LinkList() {
H = malloc(sizeof(LNode));
H->next = NULL; H->data = 0; // 頭結點
}
LinkList Add_LinkList(LinkList H) {
LinkList q = H;
while (q->next) q = q->next; // 找到尾節點
q->next = malloc(sizeof(LNode)); // 尾部直接申請內存
q->next->next = NULL;
q->next->sum = 0;
H->data++; // 總數+1
return q->next; // 返回新節點指針
}
採用**尾插法**而非教科書常見的頭插法,順序與輸入一致,更符合直覺。
void Load_LinkList(LinkList H) {
LinkList tmp = malloc(sizeof(LNode));
fp = fopen("D:/a.txt", "rb");
while (fread(tmp, sizeof(LNode), 1, fp)) {
LinkList p = Add_LinkList(H);
p->data = tmp->data;
strcpy(p->name, tmp->name);
p->price = tmp->price;
p->count = tmp->count;
H->data++;
}
free(tmp); fclose(fp);
}
void Save_LinkList(LinkList H) {
LinkList p = H->next;
fp = fopen("D:/a.txt", "wb");
if (!p) { H->data = 0; fclose(fp); return; } // 空鏈表清空文件
while (p) {
fwrite(p, sizeof(LNode), 1, fp);
p = p->next;
}
fclose(fp);
}
利用 fread/fwrite 直接按結構體大小讀寫,**避免了格式化解析的麻煩**,但要求結構體不含指針成員(本項目滿足)。
| 函數 | 功能 | 核心邏輯 |
|---|---|---|
Find_LinkList_Val | 按名稱查找 | strcmp 遍歷匹配,未找到返回 NULL |
Del_LinkList | 刪除節點 | 雙指針 pre/p 定位前驅,斷鏈 free |
Modify_LinkList | 修改信息 | 查找後重新 Scanf_LinkList 覆蓋 |
Printf_LinkList | 表格輸出 | 遍歷打印,累加頭結點 sum |
Free_LinkList | 退出釋放 | 遍歷 free 每個節點,防內存洩漏 |
int main() {
system("color A"); Creat_LinkList(); Load_LinkList(H);
while (1) {
system("cls"); menu();
switch (getch()) {
case '1': Scanf_LinkList(Add_LinkList(H)); break; // 添加
case '2': printf_header(); Printf_LinkList(H); break; // 顯示
case '3': /* 查找 */ break;
case '4': /* 修改 */ break;
case '5': /* 刪除 */ break;
case '6': Save_LinkList(H); printf("保存成功!"); break;
case '0': exit(0);
}
getch(); // 暫停查看結果
}
}
scanf 直接讀取易導致緩衝區殘留,建議改用 fgets+sscanf;這個專案讓我真正體會到「數據結構是程序的骨架,文件操作是持久化的橋樑」。下一步將嘗試用 C++ 重構:引入 std::list、fstream、RAII 管理資源,體會面向對象與泛型編程的威力。