目錄
前言:
源代碼:
product.h
?product.c
?fileio.h
?fileio.c
?main.c
代碼解析:
一、程序結構概述
二、product.c 函數詳解
1. 初始化商品列表?Init_products
2. 添加商品?add_product
3. 顯示商品?display_products
4. 修改商品?mod_product
5.刪除函數?del_product
6.查詢函數?que_product
三、main.c 主函數詳解
1. 主函數?main
2. 輔助函數?clear_screen
四、fileio.c 文件詳解
1. 保存數據到文件?save_to_file
2. 加載數據?load_from_file
3. main.c 主函數協同工作
4.聯合調試示例
五、核心知識點總結
1. 動態內存管理
2. 結構體的使用
3. 輸入輸出安全
4. 文件操作
相關運行截圖:
前言:
當前這篇博客是測試版,教大家相關添加單個商品,顯示所有商品,修改單個商品知識點;
看之前建議先看上篇博客:
(C語言)超市管理系統(測試版)(指針)(數據結構)(二進制文件讀寫)-CSDN博客
共6個文件(加上二進制文件);
源代碼:
product.h
//product.h
#pragma once //防止頭文件重復定義#define NAME_LEN 50 //商品名稱最大容量//單個商品結構體
typedef struct {int id;//商品編號char name[NAME_LEN];//商品名字float price;//商品單價int stock;//商品庫存
}Product;//商品列表表結構體
typedef struct {Product* Data;//指向單個商品數組的指針int count;//當前商品數量
}ProductList;// 函數原型
void Init_products(ProductList* list);//初始化商品列表結構體
void add_product(ProductList* list,Product* product);//添加單個商品
void display_products(ProductList* list);//顯示所有商品
void mod_product(ProductList* list, Product* product);//修改單個商品
?product.c
//product.c
#include "product.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>//初始化商品列表結構體
void Init_products(ProductList* list) {list->Data = NULL;//指針置空,防止野指針list->count = 0;//商品數量歸0
}//添加單個商品
void add_product(ProductList* list,Product* product) {//1.擴展空間Product* listnew_Data = realloc(list->Data, (list->count + 1) * sizeof(Product));if (listnew_Data==NULL) {printf("內存分配失敗!\n");exit(EXIT_FAILURE);}list->count++;list->Data = listnew_Data;//依然用老數組表示描述//2.ID自動生成list->Data[list->count - 1].id = list->count;printf("商品ID:%d\n",list->count);//3.商品信息錄入printf("請輸入商品名稱:");scanf("%49s", list->Data[list->count-1].name);printf("請輸入單價:");scanf("%f", &list->Data[list->count-1].price);printf("請輸入庫存:");scanf("%d", &list->Data[list->count-1].stock);printf("添加成功!\n");
}//顯示所有商品
void display_products(ProductList* list) {//1.判斷列表是否為空if (list->count == 0) {printf("庫存為空\n");return;}//2.打印表頭printf("\n%5s %-20s %10s %6s\n", "ID", "名稱", "單價", "庫存");printf("--------------------------------------------\n");//3.打印商品信息for (int i = 0; i < list->count; i++) {printf("%5d %-20s %10.2f %5d\n",list->Data[i].id,list->Data[i].name,list->Data[i].price,list->Data[i].stock);}
}//修改單個商品
void mod_product(ProductList* list, Product* product) {//1.判斷列表是否為空if (list->count == 0) {printf("庫存為空\n");return;}//2.輸入要修改的IDint id_0;printf("請輸入要修改的ID:");scanf("%d", &id_0);//3.判斷ID是否存在if (id_0 > list->count) {printf("ID不存在!\n");return;}//4.找要修改商品的IDint i=0;for (i; i < list->count; i++) {if (id_0 == list->Data[i].id) {break;}}//5.修改商品printf("\n%5s %-20s %10s %6s\n", "ID", "名稱", "單價", "庫存");printf("--------------------------------------------\n");printf("%5d %-20s %10.2f %5d\n",list->Data[i].id,list->Data[i].name,list->Data[i].price,list->Data[i].stock);printf("--------------------------------------------\n");printf("修改商品名稱:");scanf("%49s", list->Data[i].name);printf("修改單價:");scanf("%f", &list->Data[i].price);printf("修改庫存:");scanf("%d", &list->Data[i].stock);printf("修改成功!\n");
}
?fileio.h
//fileio.h
#pragma once
#include "product.h"// 文件操作函數原型
void save_to_file(const char* filename, const ProductList* list);
void load_from_file(const char* filename, ProductList* list);
?fileio.c
//fileio.c
//引用頭文件
#include <stdio.h>
#include <stdlib.h>
#include "product.h"// 保存數據到文件(二進制寫入)
void save_to_file(const char* filename, const ProductList* list) {//1.打開文件(二進制寫入模式)FILE* fp = fopen(filename, "wb");// "wb":二進制寫入模式,會清空原文件內容// 若文件不存在則創建新文件if (!fp) { // fp == NULL 表示打開失敗perror("保存失敗"); // 輸出錯誤信息(包含具體原因,如權限不足)exit(EXIT_FAILURE); // 終止程序,EXIT_FAILURE 表示異常退出}//2.先寫入商品數量(int 類型)fwrite(&list->count,sizeof(int),1,fp);// &list->count:取商品數量的內存地址// sizeof(int):每個元素的大小(4字節)// 1:寫入1個元素// fp:文件指針//3.再寫入所有商品數據(Product 結構體數組)fwrite(list->Data, sizeof(Product), list->count, fp);// list->Data:商品數組首地址// sizeof(Product):每個商品占用的字節數// list->count:要寫入的商品數量//4.關閉文件fclose(fp);
}// 從文件加載數據(二進制讀取)
void load_from_file(const char* filename, ProductList* list) {//1.初始化結構體(防御性編程)Init_products(&list);//初始化商品列表結構體//2.嘗試打開文件(二進制讀取模式)FILE* fp = fopen(filename, "rb");// "rb":二進制讀取模式,文件不存在時返回 NULLif (!fp) {//文件打開失敗處理return; // 保持 list 的初始狀態(count=0, Data=NULL)}//3.讀取商品數量(int 類型)fread(&list->count,sizeof(int),1,fp);// 從文件中讀取4字節到 list->count//4.根據數量分配內存list->Data = malloc(list->count * sizeof(Product));// 計算總字節數 = 商品數量 × 單個商品大小//檢查是否分配成功if (list->Data == NULL) { // list->Data == NULL 表示失敗printf("內存分配失敗\n");exit(EXIT_FAILURE); // 終止程序}//5.讀取所有商品數據fread(list->Data, sizeof(Product), list->count, fp);// 將文件內容直接讀入 Data 數組//6.關閉文件fclose(fp);
}
?main.c
//mian.c#include <stdio.h>
#include <stdlib.h>
#include "product.h"
#include "fileio.h"#define FILENAME "products.dat"//宏定義文件名//清屏操作
void clear_screen() {//判斷是否為Windows系統
#ifdef _WIN32system("cls");//其他系統
#elsesystem("clear");
#endif
}// 顯示主菜單(用戶界面)
void display_menu() {printf("\n超市管理系統\n");printf("1. 添加商品\n");printf("2. 顯示所有商品\n");printf("3. 修改商品信息\n");printf("4. 刪除商品\n");printf("5. 搜索商品\n");printf("6. 保存并退出\n");printf("請選擇操作:");
}int main() {//1.創建結構體并初始化Product product;//創建單個商品結構體ProductList list;//創建商品列表結構體Init_products(&list);//初始化//2.讀文件load_from_file(FILENAME, &list);//讀文件//3.選擇模塊int choice;//選擇選項while (1) {display_menu();//顯示菜單scanf("%d", &choice);//輸入選項switch (choice) {case 1:clear_screen();add_product(&list,&product);printf("--------------------------------------------\n");break;case 2:clear_screen();display_products(&list);printf("--------------------------------------------\n");break;case 3:clear_screen();mod_product(&list,&product);printf("--------------------------------------------\n");break;case 6:save_to_file(FILENAME, &list); // 保存數據free(list.Data); // 釋放動態內存printf("系統已退出\n");return 0; // 正確退出default:printf("無效輸入\n");}}
}
代碼解析:
一、程序結構概述
整個程序分為三個核心模塊:
數據管理模塊?(
product.c
):處理商品的增刪改查文件操作模塊?(
fileio.c
):負責數據保存與加載主控模塊?(
main.c
):協調程序流程和用戶交互
二、product.c 函數詳解
1. 初始化商品列表?
Init_products
void Init_products(ProductList* list) {list->Data = NULL; // 指針置空,防止野指針list->count = 0; // 商品數量歸0 }
功能:
初始化商品列表結構體,確保程序啟動時處于干凈狀態。
實現步驟:
Data = NULL
:將動態數組指針置空,避免指向隨機內存。
count = 0
:商品數量初始化為0。為什么這樣寫:
防御性編程:確保程序啟動時沒有殘留數據。
動態內存安全:
Data
?初始為?NULL
,realloc
?在首次調用時會自動分配內存。如何使用:
ProductList list; // 聲明一個商品列表 Init_products(&list); // 初始化列表(必須調用)
2. 添加商品?
add_product
void add_product(ProductList* list, Product* product) {// 1. 擴展內存Product* listnew_Data = realloc(list->Data, (list->count + 1) * sizeof(Product));if (listnew_Data == NULL) {printf("內存分配失敗!\n");exit(EXIT_FAILURE);}list->count++;list->Data = listnew_Data;// 2. 自動生成IDlist->Data[list->count - 1].id = list->count;printf("商品ID:%d\n", list->count);// 3. 錄入商品信息printf("請輸入商品名稱:");scanf("%49s", list->Data[list->count-1].name);printf("請輸入單價:");scanf("%f", &list->Data[list->count-1].price);printf("請輸入庫存:");scanf("%d", &list->Data[list->count-1].stock);printf("添加成功!\n"); }
功能:
動態擴展內存,添加新商品并自動生成ID。
實現步驟:
內存擴展:使用?
realloc
?將數組大小增加1個商品位置。錯誤處理:檢查內存是否分配成功,失敗則終止程序。
生成ID:新商品ID = 當前商品總數 + 1(例如第一個商品ID=1)。
輸入信息:依次輸入名稱、單價、庫存。
為什么這樣寫:
動態內存管理:
realloc
?自動處理內存擴展,無需手動復制數據。簡單ID生成:直接使用?
count
?作為ID,但存在刪除商品后ID不連續的問題(后續改進點)。如何使用:
ProductList list; Init_products(&list); add_product(&list, NULL); // 添加第一個商品
輸入示例:
請輸入商品名稱:蘋果 請輸入單價:5.5 請輸入庫存:20
注意事項:
輸入緩沖區問題:連續使用?
scanf
?可能導致殘留換行符,需清空緩沖區(代碼未處理)。名稱輸入限制:
%49s
?防止溢出,但無法輸入帶空格的名稱(如“紅富士蘋果”)。
3. 顯示商品?
display_products
void display_products(ProductList* list) {if (list->count == 0) {printf("庫存為空\n");return;}printf("\n%5s %-20s %10s %6s\n", "ID", "名稱", "單價", "庫存");printf("--------------------------------------------\n");for (int i = 0; i < list->count; i++) {printf("%5d %-20s %10.2f %5d\n",list->Data[i].id,list->Data[i].name,list->Data[i].price,list->Data[i].stock);} }
功能:
以表格形式打印所有商品信息,處理空列表情況。
實現步驟:
空列表檢查:直接返回提示信息。
打印表頭:使用格式化字符串對齊標題。
遍歷打印:循環輸出每個商品的字段。
為什么這樣寫:
用戶體驗:清晰的表格布局提升可讀性。
格式控制符:
%5d
:ID占5字符寬度,右對齊。
%-20s
:名稱左對齊,占20字符。
%10.2f
:單價保留兩位小數,總寬度10。如何使用:
display_products(&list); // 顯示當前所有商品
輸出示例:
ID 名稱 單價 庫存 --------------------------------------------1 蘋果 5.50 202 香蕉 3.80 15
4. 修改商品?
mod_product
void mod_product(ProductList* list, Product* product) {if (list->count == 0) {printf("庫存為空\n");return;}int id_0;printf("請輸入要修改的ID:");scanf("%d", &id_0);if (id_0 > list->count) {printf("ID不存在!\n");return;}int i=0;for (i; i < list->count; i++) {if (id_0 == list->Data[i].id) {break;}}// 顯示原信息并修改printf("\n%5s %-20s %10s %6s\n", "ID", "名稱", "單價", "庫存");printf("--------------------------------------------\n");printf("%5d %-20s %10.2f %5d\n",list->Data[i].id,list->Data[i].name,list->Data[i].price,list->Data[i].stock);printf("--------------------------------------------\n");printf("修改商品名稱:");scanf("%49s", list->Data[i].name);printf("修改單價:");scanf("%f", &list->Data[i].price);printf("修改庫存:");scanf("%d", &list->Data[i].stock);printf("修改成功!\n"); }
功能:
根據用戶輸入的ID查找商品,修改其信息。
實現步驟:
空列表檢查:直接返回提示。
輸入目標ID:用戶指定要修改的商品。
ID存在性檢查:錯誤判斷邏輯不嚴謹(
id_0 > count
?可能漏判)。遍歷查找:找到對應商品的數組索引。
顯示并修改:打印原信息,逐項修改。
為什么這樣寫:
直觀交互:先展示原信息再修改,減少誤操作。
直接修改內存:通過指針直接修改數組元素。
如何使用:
mod_product(&list, NULL); // 修改ID為2的商品
輸入示例:
請輸入要修改的ID:2 ...(顯示原信息)... 修改商品名稱:香蕉 修改單價:4.5 修改庫存:25
5.刪除函數?
del_product
//刪除單個商品 void del_product(ProductList* list) {//1.顯示所有商品display_products(list);printf("--------------------------------------------\n");//2.輸入要刪除的IDint id_0;printf("請輸入要刪除的ID:");scanf("%d", &id_0);//3.判斷ID是否存在if (id_0 > list->count) {printf("ID不存在!\n");return;}//4.找要刪除商品的IDint i = 0;for (i; i < list->count; i++) {//此時的i+1就是當前商品IDif (id_0 == list->Data[i].id) {break;}}//5.刪除商品for (int j = i; j < list->count - 1; j++) {list->Data[j] = list->Data[j + 1];}printf("刪除成功!\n");list->count--;//商品數量減一//6.重新生成商品IDif (list->count == 1) {list->Data[0].id = 1;}else{list->Data[list->count - 1].id = list->Data[list->count - 2].id + 1;} }
功能
根據用戶輸入的ID刪除指定商品,并調整商品列表以保持數據連續性,最后重新生成所有商品的ID以確保ID連續。
實現步驟
顯示所有商品
調用?
display_products
?顯示當前所有商品信息,供用戶參考。輸入要刪除的ID
用戶輸入目標商品的ID。
判斷ID是否存在
檢查輸入的ID是否超過當前商品總數(
id_0 > list->count
),若超過則提示不存在。查找目標商品的索引
遍歷商品列表,找到與輸入ID匹配的商品索引?
i
。刪除商品并調整數組
將索引?
i
?之后的商品依次前移一位,覆蓋目標商品。更新商品數量
減少?
list->count
?以反映刪除后的商品總數。重新生成所有商品的ID
若刪除后僅剩一個商品,將其ID設為1;否則,將最后一個商品的ID設為前一個ID加1。
為什么這樣寫
顯示商品列表:幫助用戶確認要刪除的商品ID。
簡單ID存在性檢查:假設商品ID是連續遞增的(ID = 1, 2, 3...),通過比較輸入ID與?
list->count
?快速判斷是否存在。數組前移覆蓋:通過循環將后續元素前移,邏輯簡單但效率較低(時間復雜度為O(n))。
強制ID連續:刪除后重新生成所有ID,確保ID連續,避免出現空缺(如刪除ID=2后,原ID=3變為ID=2)。
如何使用
del_product(&list); // 刪除ID為2的商品
輸入示例
(顯示所有商品) -------------------------------------------- 請輸入要刪除的ID:2 刪除成功!
6.查詢函數?
que_product
//查詢單個商品 void que_product(ProductList* list) {//1.判斷列表是否為空if (list->count == 0) {printf("庫存為空\n");return;}//2.輸入要搜索的IDint id_0;printf("請輸入要搜索的ID:");scanf("%d", &id_0);//3.判斷ID是否存在if (id_0 > list->count) {printf("ID不存在!\n");return;}//4.找要搜索商品的IDint i = 0;for (i; i < list->count; i++) {if (id_0 == list->Data[i].id) {//此時的i+1就是當前商品IDbreak;}}//5.顯示商品printf("搜索成功!\n");printf("\n%5s %-20s %10s %6s\n", "ID", "名稱", "單價", "庫存");printf("--------------------------------------------\n");printf("%5d %-20s %10.2f %5d\n",list->Data[i].id,list->Data[i].name,list->Data[i].price,list->Data[i].stock); }
功能
根據用戶輸入的ID查找并顯示指定商品的詳細信息。
實現步驟
判斷列表是否為空
若商品數量為0,直接提示庫存為空。
輸入要查詢的ID
用戶輸入目標商品的ID。
判斷ID是否存在
檢查輸入的ID是否超過當前商品總數(
id_0 > list->count
),若超過則提示不存在。查找目標商品的索引
遍歷商品列表,找到與輸入ID匹配的商品索引?
i
。顯示商品信息
以表格形式輸出該商品的ID、名稱、單價和庫存。
為什么這樣寫
快速存在性檢查:假設ID連續,通過比較輸入ID與?
list->count
?快速過濾無效ID。直接遍歷查找:線性搜索整個數組,邏輯簡單但效率較低(時間復雜度為O(n))。
格式化輸出:保持與?
display_products
?一致的表格布局,提升用戶體驗。
如何使用
que_product(&list); // 查詢ID為3的商品
輸入示例
請輸入要搜索的ID:3 搜索成功!ID 名稱 單價 庫存 --------------------------------------------3 面包 5.50 30
三、main.c 主函數詳解
1. 主函數?
main
int main() {Product product; // 單個商品(未實際使用)ProductList list; // 商品列表Init_products(&list); // 初始化列表load_from_file(FILENAME, &list); // 加載數據int choice;while (1) {display_menu(); // 顯示菜單scanf("%d", &choice);switch (choice) {case 1: add_product(&list, &product); break;case 2: display_products(&list); break;case 3: mod_product(&list, &product); break;case 6: save_to_file(FILENAME, &list); // 保存數據free(list.Data); // 釋放內存printf("系統已退出\n");return 0;default: printf("無效輸入\n");}} }
功能:
程序入口,管理整個生命周期:初始化→加載數據→循環處理用戶操作→退出保存。
實現步驟:
初始化:創建商品列表并初始化。
加載數據:從文件讀取歷史數據。
主循環:
顯示菜單,獲取用戶選擇。
調用對應功能函數。
退出處理:保存數據并釋放內存。
關鍵設計:
循環結構:
while(1)
?保持程序持續運行。內存釋放:退出前必須?
free(list.Data)
,否則內存泄漏。模塊化調用:通過?
switch-case
?調用各功能函數。用戶交互流程:
graph TD A[啟動程序] --> B[加載數據] B --> C{顯示菜單} C --> D[用戶選擇] D -->|1-5| E[執行操作] E --> C D -->|6| F[保存并退出]
2. 輔助函數?
clear_screen
void clear_screen() { #ifdef _WIN32system("cls"); // Windows清屏 #elsesystem("clear"); // Linux/Mac清屏 #endif }
功能:
清空控制臺屏幕,提升界面整潔度。
為什么這樣寫:
跨平臺兼容:通過預編譯指令區分系統。
簡單調用:
system
?函數直接執行系統命令。如何使用:
clear_screen(); // 清空屏幕后顯示新內容
四、fileio.c 文件詳解
1. 保存數據到文件?
save_to_file
void save_to_file(const char* filename, const ProductList* list) {// 1. 打開文件(二進制寫入模式)FILE* fp = fopen(filename, "wb");if (!fp) {perror("保存失敗");exit(EXIT_FAILURE);}// 2. 寫入商品數量fwrite(&list->count, sizeof(int), 1, fp);// 3. 寫入所有商品數據fwrite(list->Data, sizeof(Product), list->count, fp);// 4. 關閉文件fclose(fp); }
功能:
將商品列表數據保存到二進制文件中,確保程序退出后數據不丟失。逐行解析:
打開文件:
"wb"
:二進制寫入模式,清空原文件內容。若文件不存在則新建。
fopen
?失敗時,perror
?輸出具體錯誤(如權限不足),exit
?終止程序。寫入商品數量:
fwrite(&list->count, ...)
:將商品數量(int
?類型)寫入文件開頭。作用:后續讀取時,根據此值分配內存。
寫入商品數組:
fwrite(list->Data, ...)
:將整個商品數組寫入文件。二進制優勢:直接寫入內存數據,無需格式轉換,高效且保留浮點精度。
關閉文件:
fclose
:確保數據從緩沖區寫入磁盤。關鍵知識點:
二進制文件格式:
文件內容為原始內存數據,不可直接閱讀,但讀寫速度快。數據持久化:程序退出后,數據通過文件保存,下次啟動可恢復。
使用示例:
ProductList list; // ...添加商品... save_to_file("data.dat", &list); // 保存數據
注意事項:
跨平臺問題:不同系統可能結構體內存對齊不同,導致文件不兼容。
文件損壞風險:若寫入過程被中斷(如程序崩潰),文件可能損壞。
2. 加載數據?
load_from_file
void load_from_file(const char* filename, ProductList* list) {// 1. 初始化結構體Init_products(list);// 2. 打開文件(二進制讀取模式)FILE* fp = fopen(filename, "rb");if (!fp) return;// 3. 讀取商品數量fread(&list->count, sizeof(int), 1, fp);// 4. 分配內存list->Data = malloc(list->count * sizeof(Product));if (!list->Data) {printf("內存分配失敗\n");exit(EXIT_FAILURE);}// 5. 讀取商品數據fread(list->Data, sizeof(Product), list->count, fp);// 6. 關閉文件fclose(fp); }
功能:
從二進制文件加載商品數據到內存,恢復程序上次運行狀態。逐行解析:
初始化列表:
Init_products
?清空現有數據,防止殘留值干擾。打開文件:
"rb"
:二進制讀取模式,文件不存在時返回?NULL
,跳過加載。讀取數量:
fread(&list->count, ...)
:從文件開頭讀取商品數量。分配內存:
malloc
?根據商品數量分配足夠內存,失敗時終止程序。讀取數據:
fread
?將文件中的商品數據直接讀入?Data
?數組。關閉文件:
釋放文件資源。關鍵知識點:
防御性編程:加載前初始化列表,避免臟數據。
內存管理:動態分配的內存需在退出時通過?
free
?釋放。使用示例:
ProductList list; load_from_file("data.dat", &list); // 加載數據
注意事項:
文件驗證缺失:若文件被篡改(如數量與實際數據不符),程序會崩潰。
字節序問題:跨平臺時需處理大小端差異(如從Windows寫,Linux讀)。
3. main.c 主函數協同工作
1. 主函數代碼片段
int main() {ProductList list;Init_products(&list);load_from_file(FILENAME, &list); // 啟動時加載數據while (1) {// ...菜單處理...switch (choice) {case 6:save_to_file(FILENAME, &list); // 退出前保存free(list.Data); // 釋放內存return 0;}} }
2. 數據生命周期管理
啟動流程:
Init_products
:初始化空列表。
load_from_file
:嘗試加載數據,文件不存在則保持空列表。運行期間:
用戶通過菜單操作增刪改查,所有變動僅在內存中。
退出流程:
save_to_file
:將內存數據保存到文件。
free(list.Data)
:釋放動態數組內存,防止泄漏。3. 關鍵設計思想
數據持久化:通過文件實現“記憶功能”,關閉程序不丟數據。
資源管理:
加載時分配內存,退出時釋放,遵循“誰分配誰釋放”原則。
文件操作封裝為獨立函數,提高代碼可維護性。
4.聯合調試示例
1. 正常流程驗證
第一次運行:
添加商品:名稱=蘋果,單價=5.5,庫存=20 保存退出 → 生成data.dat文件
文件內容:
前4字節:
01 00 00 00
(數量1)后續內容:
01 00 00 00
(ID=1) + 名稱、單價、庫存的二進制數據。第二次運行:
自動加載文件,顯示已有商品。
修改庫存為30后保存退出。
2. 異常場景處理
文件被刪除:啟動時加載失敗,列表為空。
文件損壞:若手動修改文件導致數據錯亂,程序可能崩潰。
五、核心知識點總結
1. 動態內存管理
realloc
?的作用:動態調整內存大小,首次調用時等效于?malloc
。錯誤處理:必須檢查返回值是否為?
NULL
。內存釋放:
free
?必須與?malloc/realloc
?配對使用。
2. 結構體的使用
數據封裝:將商品信息打包為?
Product
?結構體。列表管理:
ProductList
?封裝動態數組和長度,提升代碼可維護性。
3. 輸入輸出安全
緩沖區溢出防護:
scanf("%49s")
?限制輸入長度。格式化輸出:
printf
?的格式控制符對齊數據。
4. 文件操作
二進制模式:
"wb"
?和?"rb"
?確保數據精確存儲。數據序列化:直接讀寫結構體內存,高效但需注意平臺兼容性。
相關運行截圖:?
?
?注:該代碼是本人自己所寫,可能不夠好,不夠簡便,歡迎大家指出我的不足之處。如果遇見看不懂的地方,可以在評論區打出來,進行討論,或者聯系我。上述內容全是我自己理解的,如果你有別的想法,或者認為我的理解不對,歡迎指出!!!如果可以,可以點一個免費的贊支持一下嗎?謝謝各位彥祖亦菲!!!!!