设计目标
1、把商品信息存放到文件中
2、程序启动时加载文件信息到数据结构中
3、根据用户选择的功能显示商店或购物车信息
4、根据用户点击的商品添加、删除商店或购物车内容
功能描述
1、侧边功能栏可以浏览商品以及购物车
2、浏览商品时选中商品自动加入购物车,若数量为0则不加入,在购物车点击商品就减少该商品的数量,减至0则移除购物车
3、购物车中显示商品信息,带有翻页功能以及统计总价
4、结账功能会在屏幕显示购物信息,并且保存到文本文件,商店信息也重写到文本,最后退出程序。
浏览商品以及购物车;选中商品自动加入购物车,在购物车点击商品就减少该商品的数量,减至0则移除购物车;购物车中显示商品信息,带有翻页功能以及统计总价;结账功能会在屏幕显示购物信息,并且保存到文本文件,商店信息也重写到文本,最后退出程序。
设计方案
设计一个哈希表存储商店信息,一条链表存储购物车信息。
链表节点结构体包括数据域与指针域,数据域结构体有商品类型、商品名、数量、价格、图片路径。指针域使用内核链表。
设计一个函数解码jpg图片并且映射到lcd
设计字库,在商品图片下面显示商品信息,在左下角提示用户的操作
循环读取用户点击位置以触发相应功能
实现过程
首先读取商店信息的文件到哈希表中,fsanf格式化输入一行一行读取文件到结构体,根据数据结构体中的类别插入到哈希表。初始化LCD,把硬件设备层/dev/fb0映射到用户层,然后显示背景。这里用的图片都是jpg格式,要先对jpg进行解码,然后把24位的jpg图片转为32位才可以在屏幕中显示,最后把转化完的argb信息映射到lcd屏幕。
打开触摸屏/dev/input/event0,循环读取用户点击的位置,如果用户点击的是商店类型,show_list遍历该种类型的哈希表,读取结构体中的商品信息,解码映射jpg图片,并在图片下方使用字库显示商品信息,在进入一个循环读入用户是否要购物,点击右侧功能栏会退出这个循环,在这个循环中,如果用户点击了商品,就会加入购物车,商品数量-1,重新显示商品信息,商品数量为0则提示添加失败。如果用户点击购物车,就会遍历购物车链表,解码映射图片,字库显示信息。点击的位置是图片就购物车数量-1,并且商店的数量会+1,如果数量为0就不会显示在购物车。在此界面设计有翻页,商品的种类超过一页,就可以翻页,第二页内容全部删除则会跳转到前一页。
最后用户点击结账就退出读取用户点击的位置的循环,利用字库显示购物信息,并且保存到文本中,关闭打开的字库、触摸屏结束进程。
实现效果:
主函数
#include "head.h"
float TOTAL_COST = 0;
int GOODS_NUM = 0;
//int (*lcd)[800]=NULL;int main()
{//write_shop.c写商店信息//1 加载商店信息到链表//初始化哈希表 struct node *hash[3]; //0.饮料, 1.水果 2.零食init_hash(hash);//初始化购物车struct list_head *cart=malloc(sizeof(struct list_head));INIT_LIST_HEAD(cart);//加载文件中的数据到哈希表中 load_shop(hash); //show_hash(hash);//显示哈希表//初始化LCDinit_lcd();//显示背景read_JPEG_file("picture/1-background.jpg",0,0);//加载字库font *f = fontLoad("/usr/share/fonts/DroidSansFallback.ttf");if(f == NULL)puts("加载字库失败");//提示框msg_tips(f,"欢迎使用XX商店系统");//打开触摸屏,在read_screen中打开// int fd = open("/dev/input/event0",O_RDWR);// if(fd<0){puts("Failed to open screen");return -1;}//读输入设备的值**************************************************read_screen(f,hash,cart);//关闭触摸屏在read_screen中操作//close(fd);//开发板显示购物车进行结账puts("\n购物信息:");show_cart(cart);printf("商品数量 %d ,共消费 %.2f 元\n",GOODS_NUM,TOTAL_COST);//显示屏幕信息display_from_cart_to_screen(cart,f);//保存小票save_ticket(cart);//关闭字库fontUnload(f); //回写商店save_shop(hash);
}//arm-linux-gcc main.c 1-数据结构.c 2-LCD.c 3-map_jpeg.c -o main -L/home/gec/jpeglib/lib -ljpeg -L./ -lm -lfont
1-数据结构.c
#include "head.h"
//#include "list.h"int GOODS_TYPE_NUM = 0;
//初始化哈希表
void init_hash(struct node *hash[3])
{for(int i=0;i<3;i++){hash[i] = malloc(sizeof(struct node)); INIT_LIST_HEAD(&hash[i]->list); }
}//加载文件
void load_shop(struct node *hash[3])
{//打开文件FILE *fp = fopen("shop.txt","r"); if(fp == NULL){puts("open shop.txt fail");return;}//不断读取文本信息 while (1){//数据结构体struct shop data; int ret = fscanf(fp,"%d %s %d %f %s\n",&data.type,data.name,&data.num,&data.price,data.pic_path);if(ret <= 0){printf("读取完毕\n");return;}//输出商品信息 //printf("%d %s %d %.2f %s\n",data.type,data.name,data.num,data.price,data.pic_path);//根据类别插入哈希表 struct node *xnew = malloc(sizeof(struct node));xnew->data = data;//插入list_add_tail(&xnew->list,&hash[data.type]->list);}
}//遍历测试
void show_hash(struct node *hash[3])
{for(int i=0;i<3;i++){struct node *pos = hash[i];list_for_each_entry(pos,&hash[i]->list,list){printf("%d %s %d %.2f %s\n",pos->data.type,pos->data.name,pos->data.num,pos->data.price,pos->data.pic_path);}}
}
//查找节点
struct node *find_node(struct list_head *head,char *name)
{struct node *pos = NULL;list_for_each_entry(pos,head,list){if(strcmp(pos->data.name,name)==0){printf("购物车中已有 %s,",pos->data.name);return pos;}}return NULL;
}//购买商品
struct shop *buy_goods(struct node *hash[3],int type,int n,struct list_head *cart)
{//int type,n;//商品类型,序号//根据序号找到商品 struct list_head *p = &hash[type]->list;p = p->next;//指向头的下一个 for(int i=0;i<n;i++)p = p->next;//取出商品 struct node *msg = list_entry(p,struct node,list);if(msg->data.num <= 0 ){printf("加入购物车失败\n");return NULL;}else {//加入购物车msg->data.num--; add_to_cart(cart,msg->data);printf("%s 加入购物车成功\n",msg->data.name);return &msg->data; //返回该商品}
}//加入购物车
void add_to_cart(struct list_head *head,struct shop data)
{struct node *xnew = find_node(head,data.name);if(xnew == NULL)//第一次加入{struct node *xnew = malloc(sizeof(struct node));xnew->data = data;xnew->data.num=1;list_add_tail(&xnew->list,head);GOODS_TYPE_NUM++;}else//多次加入购物车{xnew->data.num++;} TOTAL_COST += data.price;
}
/*加入购物车示例struct shop *s;s=buy_goods(hash,0,0);//类型,序号if(s!=NULL)puts("success");删除物品示例del_form_cart(cart,1,hash);//1购物车中的序号*///遍历购物车
void show_cart(struct list_head *head)
{struct node *pos=NULL;list_for_each_entry(pos,head,list){printf("%d %s %d %.2f %s\n",pos->data.type,pos->data.name,pos->data.num,pos->data.price,pos->data.pic_path);}
}//取消买某物
void del_form_cart(struct list_head *head,int n,struct node *hash[3])
{struct list_head *p=head->next;if(p==NULL)return;for(int i=0;i<n;i++)p=p->next;//p指向序号n,找到要删除的位置if(p==NULL)return;//找到大节点struct node *pos = list_entry(p,struct node,list);printf("删除%s\n",pos->data.name);//商店该商品数量加1struct node *shop_node=NULL;int type = pos->data.type;//商品类型list_for_each_entry(shop_node,&hash[type]->list,list){if(strcmp(shop_node->data.name,pos->data.name)==0){shop_node->data.num++;break;}}TOTAL_COST -= pos->data.price;//处理购物车 (因为可能要释放pos,所以这一步要放到最后)if(pos->data.num==1){list_del(p);//删除链表free(pos);//释放大结构体堆空间GOODS_TYPE_NUM--;} else if (pos->data.num>1){pos->data.num--;}
}//遍历一条链
void show_list(struct list_head *head,font *f)
{struct node *pos = NULL;//画图位置int i=20,j=20,j1=180,num=1;list_for_each_entry(pos,head,list){ //printf("%d %s %d %.2f %s\n",pos->data.type,pos->data.name,pos->data.num,pos->data.price,pos->data.pic_path);//显示图片read_JPEG_file(pos->data.pic_path,i,j);//显示信息char msg[1024]={0};sprintf(msg,"%s\n数量%d 价格%.2f",pos->data.name,pos->data.num,pos->data.price);display_product_information(f,i,j1,msg);i+=165;num++;if(num>4){i=20;j=240;j1=400;num=1;} }}
//可视化购物车
void show_cart_list(struct list_head *head,font *f,int page)
{//struct node *pos = NULL;struct node *pos = list_entry((head)->next, typeof(*pos), list);for(int i=0;i<page*8;i++){pos = list_entry(pos->list.next, typeof(*pos), list);}//定位到具体页码开始//画图位置int i=20,j=20,j1=180,num=1,temp=1;//list_for_each_entry(pos,head,list)for (pos; &pos->list != (head); pos = list_entry(pos->list.next, typeof(*pos), list)){ printf("%d %s %d %.2f %s\n",pos->data.type,pos->data.name,pos->data.num,pos->data.price,pos->data.pic_path);//显示图片read_JPEG_file(pos->data.pic_path,i,j);//显示信息char msg[1024]={0};sprintf(msg,"%s 数量:%d\n单价%.2f",pos->data.name,pos->data.num,pos->data.price);display_product_information(f,i,j1,msg);i+=165;num++,temp++;if(num>4){i=20;j=240;j1=400;num=1;} if(temp>8) break; }
}void save_ticket(struct list_head *head)
{FILE *fp = fopen("ticket.txt","w+");//重写if(fp==NULL){puts("open ticket.txt fail");return;}fprintf(fp,"超市小票\n");//遍历购物车struct node *pos=NULL;list_for_each_entry(pos,head,list){//printf("%d %s %d %.2f %s\n",pos->data.type,pos->data.name,pos->data.num,pos->data.price,pos->data.pic_path); fprintf(fp,"%s %.2f %d\n",pos->data.name,pos->data.price,pos->data.num);} fprintf(fp,"总消费:%.2f元\n",TOTAL_COST);fclose(fp);
}void save_shop(struct node *hash[3])
{FILE *fp = fopen("shop.txt","w+");//重写for(int i=0;i<3;i++){struct node *pos=NULL;list_for_each_entry(pos,&hash[i]->list,list)//遍历一条链{fprintf(fp,"%d %s %d %.2f %s\n",pos->data.type,pos->data.name,pos->data.num,pos->data.price,pos->data.pic_path);}}fclose(fp);
}
2-LCD.c
#include "head.h"
// #include "font.h"
// #include<unistd.h>int (*lcd)[800]=NULL;//初始化LCD
void init_lcd()
{int lcd_fd = open("/dev/fb0",O_RDWR);if(lcd_fd<0){puts("open lcd fail");return;}lcd = mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,lcd_fd,0);close(lcd_fd);
}//显示商品信息
void display_product_information(font *f,int x,int y,char *msg)
{// font *f = fontLoad("/usr/share/fonts/DroidSansFallback.ttf");// if(f == NULL)puts("加载字库失败");//2.设置字体的大小 fontSetSize(f,18);//3.设置字体输出框的大小bitmap *b = createBitmap(145,40, 4);//4.把字体输出到输出框中fontPrint(f,b,0,0, msg,0x0000ff00, 0);//颜色RGBA//5.把输出框的所有信息显示到LCD屏幕中 unsigned int *p = (void *)lcd;show_font_to_lcd(p,x,y,b);// 关闭字体库,不需要频繁关闭//fontUnload(f);// 关闭bitmapdestroyBitmap(b);
}//提醒框
void msg_tips(font *f,char *msg)
{fontSetSize(f,18);bitmap *b = createBitmap(350,20, 4);//4.把字体输出到输出框中fontPrint(f,b,0,0, msg,0xff000000, 0);//颜色RGBA//5.把输出框的所有信息显示到LCD屏幕中 unsigned int *p = (void *)lcd;show_font_to_lcd(p,0,460,b);destroyBitmap(b);
}
//获取序号
int get_seq_num()
{int fd = open("/dev/input/event0",O_RDWR);if(fd<0){puts("Failed to open screen");return -1;}int x=0,y=0,t=0;while(1){struct input_event ts;read(fd,&ts,sizeof(struct input_event));if(ts.type == EV_ABS && ts.code == ABS_X){x = ts.value*0.78125;}//printf("x=%d ",x);if(ts.type == EV_ABS && ts.code == ABS_Y){y=ts.value*0.8;}//printf("y=%d\n",y);if(ts.type == EV_KEY && ts.code == BTN_TOUCH){t=ts.value;}//printf("t=%d\n",t);//printf("x=%d y=%d t=%d\n",x,y,t);if(20<x&&x<165&&20<y&&y<200&&t==1){//puts("商品0");return 0;t=0;//按钮松开防止多次进入此条件}if(185<x&&x<330&&20<y&&y<200&&t==1)return 1;if(360<x&&x<505&&20<y&&y<200&&t==1)return 2;if(515<x&&x<660&&20<y&&y<200&&t==1)return 3;if(20<x&&x<165&&240<y&&y<420&&t==1)return 4;if(185<x&&x<330&&240<y&&y<420&&t==1)return 5;if(360<x&&x<505&&240<y&&y<420&&t==1)return 6;if(515<x&&x<660&&240<y&&y<420&&t==1)return 7;if(x>700&&y>386&&t==1)return -2;//结账if(550<x&&x<605&&y>430&&t==1)return -3;//向左if(640<x&&x<680&&y>430&&t==1)return -4;//向右翻页else if(x>700&&t==1) // ||((y>450&&x>565)){//puts("退出读取界面序号");return -1;t=0;} }
}void display_from_cart_to_screen(struct list_head *head,font *f)
{ //显示背景read_JPEG_file("picture/2-bg.jpg",0,0); unsigned int *p = (void *)lcd;fontSetSize(f,26);char msg[2048]="超市小票\n";bitmap *b = createBitmap(300,400, 4);//遍历购物车struct node *pos=NULL;list_for_each_entry(pos,head,list){printf("%d %s %d %.2f %s\n",pos->data.type,pos->data.name,pos->data.num,pos->data.price,pos->data.pic_path); sprintf(msg,"%s\n%s %.2f x%d",msg,pos->data.name,pos->data.price,pos->data.num);} sprintf(msg,"%s\n\n共消费 %.2f 元",msg,TOTAL_COST);//4.把字体输出到输出框中fontPrint(f,b,40,20, msg,0x00000000, 0);//颜色RGBA//5.把输出框的所有信息显示到LCD屏幕中 show_font_to_lcd(p,200,40,b);destroyBitmap(b);char buf[200]={0};sprintf(buf,"商品数量 %d ,共消费 %.2f 元,完整小票已保存到ticket.txt\n",GOODS_NUM,TOTAL_COST);msg_tips(f,buf);
}//读屏幕 参数 ,字库,哈希表,购物车
int read_screen(font *f,struct node *hash[3],struct list_head *cart)
{//打开触摸屏int fd = open("/dev/input/event0",O_RDWR);if(fd<0){puts("Failed to open screen");return -1;}int x_value=0,y_value=0,touch=0;while(1){struct input_event ts;read(fd,&ts,sizeof(struct input_event));if(ts.type == EV_ABS && ts.code == ABS_X){x_value = ts.value*0.78125;}if(ts.type == EV_ABS && ts.code == ABS_Y){y_value=ts.value*0.8;}if(ts.type == EV_KEY && ts.code == BTN_TOUCH){touch=ts.value;}//饮料if(x_value>700&&35<y_value&&y_value<95&&touch==1){int key=0;read_JPEG_file("picture/1-background.jpg",0,0); msg_tips(f,"正在浏览 饮料 ,点击图片加入购物车");show_list(&hash[key]->list,f); //获取序号int seq=1;while(seq!=-1)//读取当前界面购买某物{seq = get_seq_num();//失败-1//printf("seq=%d\n",seq);if(seq==-1){read_JPEG_file("picture/1-background.jpg",0,0);msg_tips(f,"点击右侧功能以继续");break;}else if(seq>=0){//加入购物车struct shop *s=NULL;s = buy_goods(hash,key,seq,cart);//类型,序号if(s==NULL){msg_tips(f,"加入购物车失败,商品缺货");}else{char msg[50]={0};sprintf(msg,"%s 加入购物车成功!",s->name);msg_tips(f,msg);show_list(&hash[key]->list,f);GOODS_NUM++;}} } x_value=0,y_value=0,touch=0;}//水果if(x_value>700&&110<y_value&&y_value<173&&touch==1){int key = 1;read_JPEG_file("picture/1-background.jpg",0,0); msg_tips(f,"正在浏览 水果");SCREEN(key);//宏函数,跟饮料的操作一样x_value=0,y_value=0,touch=0;}//零食if(x_value>700 && 186<y_value&& y_value<250 &&touch==1){int key = 2;read_JPEG_file("picture/1-background.jpg",0,0);msg_tips(f,"正在浏览 零食");SCREEN(key);//宏函数,跟饮料的操作一样x_value=0,y_value=0,touch=0;}//购物车if(x_value>700&&310<y_value&&y_value<375&&touch==1){int cart_page=0;//购物车页码//显示背景read_JPEG_file("picture/2-bg.jpg",0,0); //显示购物车信息show_cart_list(cart,f,cart_page);char buf[100]={0};sprintf(buf,"数量 %d,产生消费 %.2f元,第%d页/共%d页,点击右下角进行结算\n",GOODS_NUM,TOTAL_COST,cart_page+1,((GOODS_TYPE_NUM-1)/8)+1);msg_tips(f,buf); //获取序号,大于0购物车内容,小于0其他内容int seq=0;while(1)//读取当前界面购买某物{seq=-1;seq = get_seq_num();//点击屏幕右侧返回-1if(seq==-1||seq==-2){read_JPEG_file("picture/1-background.jpg",0,0);msg_tips(f,"点击右侧功能以继续");break;}else if(seq == -3)//向左翻页{ if(cart_page>0){puts("向左翻页");cart_page--;read_JPEG_file("picture/2-bg.jpg",0,0);show_cart_list(cart,f,cart_page);//消息框//char buf[50]={0};memset(buf,0,100);//sprintf(buf,"当前浏览第%d页,共%d页",cart_page+1,(GOODS_TYPE_NUM-1)/8+1);sprintf(buf,"数量 %d,产生消费 %.2f元,第%d页/共%d页\n",GOODS_NUM,TOTAL_COST,cart_page+1,((GOODS_TYPE_NUM-1)/8)+1);msg_tips(f,buf);} }else if(seq == -4)//向右翻页{ if(GOODS_NUM>0 && (cart_page<(GOODS_TYPE_NUM-1)/8)){puts("向右翻页"); cart_page++;read_JPEG_file("picture/2-bg.jpg",0,0);show_cart_list(cart,f,cart_page);//消息框//char buf[50]={0};memset(buf,0,100);sprintf(buf,"数量 %d,产生消费 %.2f元,第%d页/共%d页\n",GOODS_NUM,TOTAL_COST,cart_page+1,((GOODS_TYPE_NUM-1)/8)+1);msg_tips(f,buf);} } //删除某物else if(seq>=0){//移除购物车seq += cart_page*8;//具体页码的序号if(seq>=GOODS_TYPE_NUM)continue;del_form_cart(cart,seq,hash);//seq购物车中的类型序号GOODS_NUM--;//显示背景read_JPEG_file("picture/2-bg.jpg",0,0);//清除残留if(GOODS_NUM>0&&(cart_page>(GOODS_TYPE_NUM-1)/8))//减一页cart_page--;//显示购物车信息memset(buf,0,100);sprintf(buf,"数量 %d,产生消费 %.2f元,第%d页/共%d页\n",GOODS_NUM,TOTAL_COST,cart_page+1,((GOODS_TYPE_NUM-1)/8)+1);show_cart_list(cart,f,cart_page);msg_tips(f,buf); } } if(seq==-2)break;//结账x_value=0,y_value=0,touch=0;}}//循环读取屏幕close(fd);
}
3-map-jpeg.c
#include <stdio.h>
#include "/home/gec/jpeglib/include/jpeglib.h"
#include <setjmp.h>
#include<stdlib.h>#include"head.h"//int (*lcd)[800];struct my_error_mgr {struct jpeg_error_mgr pub; /* "public" fields */jmp_buf setjmp_buffer; /* for return to caller */
};typedef struct my_error_mgr * my_error_ptr;METHODDEF(void) my_error_exit (j_common_ptr cinfo)
{my_error_ptr myerr = (my_error_ptr) cinfo->err;(*cinfo->err->output_message) (cinfo);longjmp(myerr->setjmp_buffer, 1);
}/*
JPEG解压缩的示例例程,成功时返回1,错误时返回0*/GLOBAL(int) read_JPEG_file (char * filename,int sx,int sy)
{struct jpeg_decompress_struct cinfo;struct my_error_mgr jerr;/* More stuff */FILE * infile; /* source file */JSAMPARRAY buffer; /* Output row buffer */int row_stride; /* physical row width in output buffer */if ((infile = fopen(filename, "rb")) == NULL) {fprintf(stderr, "can't open %s\n", filename);return 0;}/* Step 1:分配并初始化JPEG解压缩对象*//* We set up the normal JPEG error routines, then override error_exit. */cinfo.err = jpeg_std_error(&jerr.pub);jerr.pub.error_exit = my_error_exit;/* Establish the setjmp return context for my_error_exit to use. */if (setjmp(jerr.setjmp_buffer)) {/* If we get here, the JPEG code has signaled an error.* We need to clean up the JPEG object, close the input file, and return.*/jpeg_destroy_decompress(&cinfo);fclose(infile);return 0;}/* Now we can initialize the JPEG decompression object. */jpeg_create_decompress(&cinfo);/* Step 2:指定数据源(eg, a file) */jpeg_stdio_src(&cinfo, infile);/* Step 3: 读取文件参数 */(void) jpeg_read_header(&cinfo, TRUE);/* Step 5: 启动解压缩程序*/(void) jpeg_start_decompress(&cinfo);/* 初始化输入行*/row_stride = cinfo.output_width * cinfo.output_components;buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);/* Step 6: while (扫描读取) */
//重点
//打印图片信息//printf("width=%d height=%d bit=%d\n",cinfo.output_width,cinfo.output_height,cinfo.output_components);if(cinfo.output_width>800||cinfo.output_height>480){puts("图片太大");return 0;}//cinfo.output_width=800;cinfo.output_height=480;char argb[cinfo.output_height][cinfo.output_width*4];int y=0;while (cinfo.output_scanline < cinfo.output_height){(void) jpeg_read_scanlines(&cinfo, buffer, 1);/* 指针和样本计数 *///put_scanline_someplace(buffer[0], row_stride);//转32位for(int x=0;x<cinfo.output_width;x++){argb[y][3+4*x] = 0; //aargb[y][2+4*x] = buffer[0][0+3*x]; //rargb[y][1+4*x] = buffer[0][1+3*x]; //gargb[y][0+4*x] = buffer[0][2+3*x]; //b}y++;}//映射int (*color)[cinfo.output_width] = (void *)argb;for(int y=0;y<cinfo.output_height;y++)for(int x=0;x<cinfo.output_width;x++)if(y+sy<480&&x+sx<800){lcd[y+sy][x+sx] = color[y][x];}/* Step 7: 完成解压缩*/(void) jpeg_finish_decompress(&cinfo);/* Step 8: 释放JPEG解压缩对象*/jpeg_destroy_decompress(&cinfo);fclose(infile);return 1;
}
写商店信息,
write_shop.c
#include<stdio.h>
#include<string.h>#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>#include<unistd.h>//商店结构体
struct shop{int type;char name[50];int num;float price;char pic_path[1024];
};void save_shop(int type,char *name,int num,float price,char* path)
{//打开商店文件FILE *fp = fopen("shop.txt","a+");if(fp==NULL){puts("open shop.txt fail");return;}//写文件fprintf(fp,"%d %s %d %.2f %s\n",type,name,num,price,path);fclose(fp);
}void load_shop()
{FILE *fp = fopen("shop.txt","r");while(1){// char name[50],path[1024];// int num,type;// float price;struct shop s;int ret = fscanf(fp,"%d %s %d %f %s\n",&s.type,s.name,&s.num,&s.price,s.pic_path);if(ret == -1)break;//读取完毕printf("%d %s %d %.2f %s\n",s.type,s.name,s.num,s.price,s.pic_path);}fclose(fp);
}int main()
{save_shop(0,"可乐",100,2.5,"picture/kele.jpg"); save_shop(0,"芬达",1,3.5,"picture/fenda.jpg");save_shop(0,"王老吉",56,5,"picture/wanglaoji.jpg");save_shop(0,"加多宝",57,5,"picture/jiaduobao.jpg");save_shop(0,"牛奶",83,3.5,"picture/niunai.jpg"); save_shop(0,"冰红茶",1,4,"picture/binghongcha.jpg");save_shop(0,"阿萨姆",95,4,"picture/asamu.jpg");save_shop(0,"雪碧",27,3,"picture/xuebi.jpg");save_shop(1,"苹果",40,6.4,"picture/apple.jpg");save_shop(1,"香蕉",36,13.8,"picture/banana.jpg");save_shop(1,"凤梨",52,39,"picture/fengli.jpg");save_shop(1,"奇异果",38,48.5,"picture/qiyiguo.jpg");save_shop(1,"火龙果",42,37,"picture/huolongguo.jpg");save_shop(1,"牛油果",49,52,"picture/niuyouguo.jpg");save_shop(1,"葡萄",52,68.8,"picture/putao.jpg");save_shop(1,"橙子",35,34.5,"picture/chengzi.jpg");save_shop(2,"薯片",38,22.6,"picture/shupian.jpg");save_shop(2,"铜锣烧",49,16.9,"picture/tongluoshao.jpg");save_shop(2,"奥利奥",21,19.9,"picture/aoliao.jpg");save_shop(2,"辣条",39,13.5,"picture/latiao.jpg");save_shop(2,"饼干",49,43,"picture/binggan.jpg");save_shop(2,"好丽友",32,35,"picture/haoliyou.jpg");save_shop(2,"蛋卷",44,65,"picture/danjuan.jpg");save_shop(2,"巧克力",29,36.5,"picture/qiaokeli.jpg");load_shop();}