题目
问题描述:有一家商店,为了查看店里有些什么商品、数量有多少以及每件商品的价格如何,需要编制一份商品目录。每种商品都包括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循环就好了。
┆凉┆暖┆降┆等┆幸┆我┆我┆里┆将┆ ┆可┆有┆谦┆戮┆那┆ ┆大┆始┆ ┆然┆
┆薄┆一┆临┆你┆的┆还┆没┆ ┆来┆ ┆是┆来┆逊┆没┆些┆ ┆雁┆终┆ ┆而┆
┆ ┆暖┆ ┆如┆地┆站┆有┆ ┆也┆ ┆我┆ ┆的┆有┆精┆ ┆也┆没┆ ┆你┆
┆ ┆这┆ ┆试┆方┆在┆逃┆ ┆会┆ ┆在┆ ┆清┆来┆准┆ ┆没┆有┆ ┆没┆
┆ ┆生┆ ┆探┆ ┆最┆避┆ ┆在┆ ┆这┆ ┆晨┆ ┆的┆ ┆有┆来┆ ┆有┆
┆ ┆之┆ ┆般┆ ┆不┆ ┆ ┆这┆ ┆里┆ ┆没┆ ┆杀┆ ┆来┆ ┆ ┆来┆