题目
问题描述:有一家商店,为了查看店里有些什么商品、数量有多少以及每件商品的价格如何,需要编制一份商品目录。每种商品都包括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文件不存在会出错。
代码语言:javascript复制#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) 商品名tttt数量t价格n");
for(i=1; i<=cnt; i )
printf("%-10dt %-35st%-4dt%-4.2lfn",
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) 商品名tttt数量t价格n");
printf("%-10dt %-35st%-4dt%-4.2lfn",
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("请输入正确IDn");
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("请输入正确IDn");
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) 商品名tttt数量t价格n");
for(i=0; i<100; i )
{
if(strlen(a[i].name)!=0)
{
printf("%-10dt %-35st%-4dt%-4.2lfn",
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循环就好了。