首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C語言商品資訊管理系統開發實戰:鏈結串列、檔案持久化與常見坑點

     編輯:關於C語言

系統架構

  • 資料結構:單向鏈結串列,節點含商品屬性(名稱、編號、產地、進貨日期、供應商、單價、庫存)
  • 持久化:文字檔 goods.txt,啟動時載入、新增時追加
  • 介面:主選單(錄入/刪除/查詢/修改/插入/退出)

核心資料結構

typedef struct Goods {
    char name[50];
    char number[20];
    char origin[50];
    char purchase_date[20];
    char supplier[50];
    int price;
    int stock;
    struct Goods *next;
    int index;  // 原始節點序號
} Goods;

關鍵函數實現

檔案讀取初始化

Goods* load_from_file() {
    FILE *fp = fopen("goods.txt", "r");
    if (!fp) {
        fp = fopen("goods.txt", "w"); // 不存在則建立
        if (!fp) return NULL;
    }
    fclose(fp);
    
    fp = fopen("goods.txt", "r");
    Goods *head = NULL, *tail = NULL;
    char line[512];
    while (fgets(line, sizeof(line), fp)) {
        Goods *node = malloc(sizeof(Goods));
        sscanf(line, "%d %49s %19s %49s %19s %49s %d %d",
               &node->index, node->name, node->number, node->origin,
               node->purchase_date, node->supplier, &node->price, &node->stock);
        node->next = NULL;
        if (!head) head = tail = node;
        else { tail->next = node; tail = node; }
    }
    fclose(fp);
    return head;
}

新增商品並寫入檔案

void save_to_file(Goods *node) {
    FILE *fp = fopen("goods.txt", "a");
    if (!fp) return;
    fprintf(fp, "%d %s %s %s %s %s %d %d\n",
            node->index, node->name, node->number, node->origin,
            node->purchase_date, node->supplier, node->price, node->stock);
    fclose(fp);
}

鏈結串列刪除節點

Goods* delete_node(Goods *head, Goods *target) {
    if (!head || !target) return head;
    if (head == target) {
        Goods *tmp = head->next;
        free(head);
        return tmp;
    }
    Goods *prev = head;
    while (prev->next && prev->next != target) prev = prev->next;
    if (prev->next) {
        prev->next = target->next;
        free(target);
    }
    return head;
}

實戰踩坑記錄

  1. 檔案不存在導致閃退:fopen(..., "r") 要求檔案必須存在 → 先用 "w" 建立再用 "r" 讀取
  2. 控制台一閃而過:讀取失敗 exit(1) 直接結束 → 加入 getchar() 暫停觀察錯誤訊息
  3. 隱藏副檔名導致雙重副檔名:Windows 預設隱藏副檔名,實際檔名為 goods.txt.txt → 程式檢查檔案存在性時用 fopen 實測而非檔名字串
  4. scanf 留下換行符:混用 scanf 與 fgets/getline 時需清理緩衝區

編譯環境修正

  • 原碼混用 C/C++(iostream、string、new/delete) → 純 C 版本改用 stdio.h、stdlib.h、string.h、malloc/free
  • 結構體中 string 改為定長字元陣列
  • _getch() 為 MSVC 專用,跨平台可用 getchar() 或 termios 非緩衝讀取

擴展建議

  • 加入排序功能(按單價/庫存)
  • 實作二分搜尋(需轉為陣列或平衡樹)
  • 引入 SQLite 替代文字檔,支援並發與複雜查詢
  • 介面改用 ncurses 實現文字模式視窗化
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved