题目

问题描述:有一家商店,为了查看店里有些什么商品、数量有多少以及每件商品的价格如何,需要编制一份商品目录。每种商品都包括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循环就好了。


┆凉┆暖┆降┆等┆幸┆我┆我┆里┆将┆ ┆可┆有┆谦┆戮┆那┆ ┆大┆始┆ ┆然┆
┆薄┆一┆临┆你┆的┆还┆没┆ ┆来┆ ┆是┆来┆逊┆没┆些┆ ┆雁┆终┆ ┆而┆
┆ ┆暖┆ ┆如┆地┆站┆有┆ ┆也┆ ┆我┆ ┆的┆有┆精┆ ┆也┆没┆ ┆你┆
┆ ┆这┆ ┆试┆方┆在┆逃┆ ┆会┆ ┆在┆ ┆清┆来┆准┆ ┆没┆有┆ ┆没┆
┆ ┆生┆ ┆探┆ ┆最┆避┆ ┆在┆ ┆这┆ ┆晨┆ ┆的┆ ┆有┆来┆ ┆有┆
┆ ┆之┆ ┆般┆ ┆不┆ ┆ ┆这┆ ┆里┆ ┆没┆ ┆杀┆ ┆来┆ ┆ ┆来┆