題目
問題描述:有一家商店,為了查看店里有些什么商品、數量有多少以及每件商品的價格如何,需要編制一份商品目錄。每種商品都包括4種屬性:商品ID、商品名、數量與價格。商品ID為0—99之間的整數,每種商品的ID號互不相同,所以這里默認只有100種商品;商品名只包含大小寫字母與空格,長度不超過35個字符;商品數量的范圍是0—99999;商品的價格為一個非負的浮點數。
你要幫助商店設計一個二進制文件,存儲該商店的所有商品情況。下表為該商店商品清單的樣例。
記錄號(商品ID) |
商品名 |
數量 |
價格 |
5 |
Lamp |
23 |
5.99 |
8 |
Screwdriver |
9 |
7.99 |
10 |
Hammer |
10 |
12.00 |
13 |
Bicycle |
5 |
100.99 |
16 |
Optical mouse |
21 |
11.50 |
25 |
keyboard |
32 |
59.99 |
要求:
1.設計一個結構,來表示一件商品。
2.創建名為“commodity.dat”的二進制文件,存儲該商店商品信息,初始化為100條空記錄,用商品ID作為記錄號。
3.實現對“commodity.dat”中商品信息的初始化錄入。
4.實現對“commodity.dat”中商品信息的更新,其中記錄號不可以更新,其他三項信息均可更新。
5.實現對“commodity.dat”中商品信息的刪除。
6.實現對“commodity.dat”中商品信息的輸出。
7.上述2~6項中對文件的初始化、記錄的刪除和更新、文件信息的輸出這些功能,都分別定義成單獨的函數。
程序運行效果:
請輸入您的選擇:
1--創建一個100條空記錄的文件
2--輸入商品記錄
3--更新商品記錄
4--刪除商品記錄
5--輸出商品記錄
[選擇]1↙
100條空記錄創建完畢
請輸入您的選擇:
1--創建一個100條空記錄的文件
2--輸入商品記錄
3--更新商品記錄
4--刪除商品記錄
5--輸出商品記錄
[選擇]2↙
請輸入商品信息[記錄號為-1代表輸入結束]:
商品ID:5↙
商品名:Lamp↙
數量:23↙
價格:5.99↙
請輸入商品信息[記錄號為-1代表輸入結束]:
商品ID: 8↙
商品名:Screwdriver↙
數量:9↙
價格:7.99↙
請輸入商品信息[記錄號為-1代表輸入結束]:
商品ID: 10↙
商品名:Hammer↙
數量:10↙
價格:12.00↙
請輸入商品信息[記錄號為-1代表輸入結束]:
-1↙
商品信息如下:
記錄號(商品ID) 商品名 數量 價格
5 Lamp 23 5.99
8 Screwdriver 9 7.99
10 Hammer 10 12.00
請輸入您的選擇:
1--創建一個100條空記錄的文件
2--輸入商品記錄
3--更新商品記錄
4--刪除商品記錄
5--輸出商品記錄
[選擇]3↙
請輸入待更新商品ID:
8↙
原商品信息如下:
記錄號(商品ID) 商品名 數量 價格
8 Screwdriver 9 7.99
請輸入更新信息[如某項不更新請直接按回車鍵]:
商品名:↙
數量:7↙
價格:9.99↙
更新后商品信息如下:
記錄號(商品ID) 商品名 數量 價格
8 Screwdriver 7 9.99
請輸入您的選擇:
1--創建一個100條空記錄的文件
2--輸入商品記錄
3--更新商品記錄
4--刪除商品記錄
5--輸出商品記錄
[選擇]5↙
商品信息如下:
記錄號(商品ID) 商品名 數量 價格
5 Lamp 23 5.99
8 Screwdriver 7 9.99
10 Hammer 10 12.00
請輸入您的選擇:
1--創建一個100條空記錄的文件
2--輸入商品記錄
3--更新商品記錄
4--刪除商品記錄
5--輸出商品記錄
[選擇]3↙
請輸入待更新商品ID:
90↙
對不起,不存在該商品,無法進行更新操作
請輸入您的選擇:
1--創建一個100條空記錄的文件
2--輸入商品記錄
3--更新商品記錄
4--刪除商品記錄
5--輸出商品記錄
[選擇]4↙
請輸入待刪除商品ID:
8↙
刪除成功
請輸入您的選擇:
1--創建一個100條空記錄的文件
2--輸入商品記錄
3--更新商品記錄
4--刪除商品記錄
5--輸出商品記錄
[選擇]5↙
商品信息如下:
記錄號(商品ID) 商品名 數量 價格
5 Lamp 23 5.99
10 Hammer 10 12.00
請輸入您的選擇:
1--創建一個100條空記錄的文件
2--輸入商品記錄
3--更新商品記錄
4--刪除商品記錄
5--輸出商品記錄
[選擇]4↙
請輸入待刪除商品ID:
8↙
對不起,不存在該商品,無法進行刪除操作
請輸入您的選擇:
1--創建一個100條空記錄的文件
2--輸入商品記錄
3--更新商品記錄
4--刪除商品記錄
5--輸出商品記錄
1
100條空記錄創建完畢
請輸入您的選擇:
1--創建一個100條空記錄的文件
2--輸入商品記錄
3--更新商品記錄
4--刪除商品記錄
5--輸出商品記錄
2
請輸入商品信息[記錄號為-1代表輸入結束]:
記錄號:5
商品名:Lamp
數量:23
價格:5.99
請輸入商品信息[記錄號為-1代表輸入結束]:
記錄號:8
商品名:Screwdriver
數量:9
價格:7.99
請輸入商品信息[記錄號為-1代表輸入結束]:
記錄號:10
商品名:Hammer
數量:10
價格:12.00
請輸入商品信息[記錄號為-1代表輸入結束]:
-1
代碼
注意:運行前,在這個c文件的同一個目錄下新建一個commodity.dat,因為模式是rb+,如果commodity.dat文件不存在會出錯。
#include<stdio.h> #include<string.h> /*-------------------------------------- 定義結構體struct Commodity,別名為cd。 id 商品ID name 商品名 num 數量 price 價格 數組a以內存形式存放商品信息。 --------------------------------------*/ typedef struct Commodity { int id; char name[40]; int num; double price; } cd; /*-------------------------------------- 輸出ID數組中的商品數據: ________________________________________________ |商品信息如下: |記錄號(商品ID)商品名 數量 價格 |xx xxx xx xx |xx xxx xx xx |xx xxx xx xx ———————————————————————————————————————————————— --------------------------------------*/ void print(FILE *f,int id[],int cnt) { int i; cd a[105]; memset(a,0,sizeof a); rewind(f); fread(a,sizeof(cd),100,f); printf("商品信息如下:\n"); printf("記錄號(商品ID) 商品名\t\t\t\t數量\t價格\n"); for(i=1; i<=cnt; i++) printf("%-10d\t %-35s\t%-4d\t%-4.2lf\n", id[i],a[id[i]].name,a[id[i]].num,a[id[i]].price); } /*-------------------------------------- 輸出ID商品數據: ___________________________________________________ |商品信息如下: |記錄號(商品ID) 商品名 數量 價格 |xx xxx xx xx ———————————————————————————————————————————————————— --------------------------------------*/ void print1(FILE *f,int id) { int i; cd a; fseek(f,id*sizeof(cd),SEEK_SET); fread(&a,sizeof(cd),1,f); printf("商品信息如下:\n"); printf("記錄號(商品ID) 商品名\t\t\t\t數量\t價格\n"); printf("%-10d\t %-35s\t%-4d\t%-4.2lf\n", id,a.name,a.num,a.price); } /*-------------------------------------- 讀取數據,只讀到回車則返回-1 --------------------------------------*/ double read() { double k=10,a=0,ok=0; char c; while((c=getchar())!='\n') { ok=1; if(isdigit(c)) { if(k==10) a=a*k+c-'0'; else { a=a+(c-'0')*k; k*=0.1; } } else if(c=='.') k=0.1; }; if(ok) return a; else return -1; } /*-------------------------------------- 初始化100條空記錄寫入文件 --------------------------------------*/ void init(FILE *f) { int i; cd a[105]; memset(a,0,sizeof a); for(i=0; i<100; i++) a[i].id=i;//設置id rewind(f); fwrite(a, sizeof(cd),100, f);//將100條數據寫入文件 printf("100條空記錄創建完畢\n"); } /*-------------------------------------- 增加商品信息 --------------------------------------*/ void add(FILE *f) { cd a[105]; memset(a,0,sizeof a); rewind(f); fread(a, sizeof(cd),100, f); int i,j,id[105],cnt=0; while(1)//直到商品ID輸入為-1 { printf("請輸入商品信息[記錄號為-1代表輸入結束]:\n商品ID:"); scanf("%d",&j); if(j==-1)break; printf("商品名:"); scanf("%s",&a[j].name);//增加的商品數據存在a數組中。 printf("數量:"); scanf("%d",&a[j].num); printf("價格:"); scanf("%lf",&a[j].price); id[++cnt]=j;//增加的商品ID臨時存放在id數組中 } rewind(f);//將指針指向文件開頭 fwrite(a,sizeof(cd),100,f);//全部重新寫入文件 print(f,id,cnt);//輸出增加的商品信息 } /*-------------------------------------- 更新商品信息 --------------------------------------*/ void update(FILE *f) { cd a[105]; memset(a,0,sizeof a); rewind(f); fread(a, sizeof(cd),100, f); int i; printf("請輸入待更新商品ID:\n"); while(scanf("%d",&i)&&i<-1)printf("請輸入正確ID\n"); if(i==-1)return; if(strlen(a[i].name)==0) printf("對不起,不存在該商品,無法進行更新操作\n"); else { printf("原"); print1(f,i);//再輸出原商品信息 printf("請輸入更新信息[如某項不更新請直接按回車鍵]:\n"); printf("商品名:"); char c; getchar(); memset(a[i].name,0,sizeof(a[i].name)); int j=0; while((c=getchar())!='\n') a[i].name[j++]=c; double tmp; printf("數量:"); tmp=read(); if(tmp!=-1)a[i].num=(int)tmp; printf("價格:"); tmp=read(); if(tmp!=-1)a[i].price=tmp; fseek(f,i*sizeof(cd),SEEK_SET);//跳過前面i塊位置,因為i是0-99,所以不用i-1 fwrite(&a[i],sizeof(cd),1,f);//新數據寫入文件 printf("更新后");//輸出更新后的商品信息 print1(f,i); } } /*-------------------------------------- 刪除商品信息 --------------------------------------*/ void delete(FILE *f) { int id; cd a[105]; memset(a,0,sizeof a); rewind(f); fread(a, sizeof(cd),100, f); printf("請輸入待刪除商品ID:\n"); while(scanf("%d",&id)&&id<-1)printf("請輸入正確ID\n"); if(id==-1)return; if(strlen(a[id].name)==0) printf("對不起,不存在該商品,無法進行刪除操作\n"); else { memset(a[id].name,0,sizeof(a[id].name)); a[id].num=0; a[id].price=0; fseek(f,id*sizeof(cd),SEEK_SET); fwrite(&a[id],sizeof(cd),1,f); printf("刪除%d成功\n",id); } } /*-------------------------------------- 輸出商品信息 --------------------------------------*/ void output(FILE *f) { int i; cd a[105]; memset(a,0,sizeof a); rewind(f); fread(a,sizeof(cd),100,f); printf("商品信息如下:\n"); printf("記錄號(商品ID) 商品名\t\t\t\t數量\t價格\n"); for(i=0; i<100; i++) { if(strlen(a[i].name)!=0) { printf("%-10d\t %-35s\t%-4d\t%-4.2lf\n", i,a[i].name,a[i].num,a[i].price); } } } int main() { FILE *f=fopen("commodity.dat","rb+");//讀寫,不清空,覆蓋寫。 while(1)//使程序一直循環 { int i; printf("請輸入您的選擇:\n"); printf("1--創建一個100條空記錄的文件\n2--輸入商品記錄\n3--更新商品記錄\n4--刪除商品記錄\n5--輸出商品記錄\n"); printf("[選擇]"); scanf("%d",&i); if(i==-1)break;//-1結束程序 else if(i==1)init(f); else if(i==2)add(f); else if(i==3)update(f); else if (i==4)delete(f); else if(i==5)output(f); else continue; getchar(); getchar(); printf("\n"); } fclose(f); return 0; }
還是,歡迎同學們找出bug。
*bug修復-165行的樣子:2016.4.5 21:59 輸入3更新時如果名字只有一個字符時停在那了,改成getchar循環就好了。