链表数据无法存入文件
跪求各位大佬能帮小弟看一下,这是我们的C语言大作业,但是代码写完之后有两个问题:1、在删除链表数据时不能删除第一个节点的数据,也就是最新录入的删不掉。
2、因为在其他部分也需要调用链表数据,但是回到主函数时候链表就被清空了,并没有把数据保存到文件里面。在网上搜了很多帖子仍然解决不了,人都傻了{:10_266:}
"""
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*-----信息存储区-----*/
struct Caipin{
char cai;
int price;
}caipin={ //7种菜品
{"steak",50},{"lamb",30},{"bacon",25},{"chicken",30},
{"vegetable",15},{"meatball",20},{"lobster",100}
};
struct Zhushi{
char zhu;
int price;
}zhushi={ //5种主食
{"rice",5},{"cake",3},{"noodles",7},
{"jiaozi",20},{"bun",10}
};
struct Yinliao{
char yin;
int price;
}yinliao={ //5种饮料
{"juice",3},{"coca-cola",5},{"tea",20},
{"coffee",15},{"milk",7}
};
struct VIP{ //用链表形式保存会员信息
char name;
char tel;
struct VIP *next;
};
/*-----函数声明区-----*/
int diancan();
int choice_caipin();
int choice_zhushi();
int choice_yinliao();
int jiesuan(int sum);
struct VIP *check_huiyuan(struct VIP *infor,char *input);
int huiyuan();
void getInput(struct VIP *infor);
void huiyuan_upload(struct VIP **xinxi);
void huiyuan_print(struct VIP *infor);
void huiyuan_delete(struct VIP *infor);
void saveVIP(struct VIP *xinxi);
struct VIP *readVIP();
/*-----主函数区-----*/
int main()
{
struct VIP *infor;
infor = readVIP();
saveVIP(infor);
printf("欢迎使用XX餐厅前台管理系统\n");
printf("请选择您需要的服务项目:\n");
printf("1\t点餐\n2\t结算\n3\t会员卡管理\n");
int temp=0;
double sum = 0;
while(1){
scanf("%d",&temp);
switch(temp)
{
case 1:sum = diancan();break; //进入点餐界面
case 2:jiesuan(sum);break; //进入结算系统
case 3:huiyuan();break; //进入会员管理系统
default:printf("输入错误!请重新输入");
}
}
return 0;
}
/*-----点餐函数区-----*/
int diancan()
{
printf("欢迎点餐!\n");
printf("请选择:\n1\t菜品\n2\t主食\n3\t饮料\n0\t返回主菜单\n");
int temp;
int sum = 0;
while(1){
scanf("%d",&temp);
switch(temp)
{
case 1:
sum += choice_caipin();
printf("请选择:\n1\t菜品\n2\t主食\n3\t饮料\n0\t返回主菜单\n");
break; //调用菜品选择函数,并计算总价格
case 2:
sum += choice_zhushi();
printf("请选择:\n1\t菜品\n2\t主食\n3\t饮料\n0\t返回主菜单\n");
break; //调用主食选择函数,并计算总价格
case 3:
sum += choice_yinliao();
printf("请选择:\n1\t菜品\n2\t主食\n3\t饮料\n0\t返回主菜单\n");
break; //调用饮料选择函数,并计算总价格
case 0:printf("1\t点餐\n2\t结算\n3\t会员卡管理\n");return sum; //返回主菜单
default:printf("输入错误!请重新输入");break;
}
}
}
int choice_caipin()
{
printf("请选择菜品:\n");
for(int i=0;i<7;i++){
printf("%d\t%s\t\t%d\n",i+1,caipin.cai,caipin.price);
}
printf("输入0返回上一级\n");
int choice;
int sum_caipin = 0;
while(1){
scanf("%d",&choice);
if(choice == 0){
break;
}
for (int j=0;j<7;j++){
if(choice == j+1){
printf("%s已选择\n",caipin.cai);
sum_caipin += caipin.price;
}
}
}
return sum_caipin;
}
int choice_zhushi()
{
printf("请选择主食:\n");
for(int i=0;i<5;i++){
printf("%d\t%s\t\t%d\n",i+1,zhushi.zhu,zhushi.price);
}
printf("输入0返回上一级\n");
int choice;
int sum_zhushi = 0;
while(1){
scanf("%d",&choice);
if(choice == 0){
break;
}
for (int j=0;j<7;j++){
if(choice == j+1){
printf("%s已选择\n",zhushi.zhu);
sum_zhushi += zhushi.price;
}
}
}
return sum_zhushi;
}
int choice_yinliao()
{
printf("请选择主食:\n");
for(int i=0;i<5;i++){
printf("%d\t%s\t\t%d\n",i+1,yinliao.yin,yinliao.price);
}
printf("输入0返回上一级\n");
int choice;
int sum_yinliao = 0;
while(1){
scanf("%d",&choice);
if(choice == 0){
break;
}
for (int j=0;j<7;j++){
if(choice == j+1){
printf("%s已选择\n",yinliao.yin);
sum_yinliao += yinliao.price;
}
}
}
return sum_yinliao;
}
/*-----结算函数区-----*/
int jiesuan(int sum)
{
printf("您本次消费 %d 元",sum);
int temp = 1;
double rate = 0.7;
struct VIP *infor = NULL;
char input;
while(temp == 1){
printf("您是否有会员卡?\n");
printf("1\t有\n0\t没有\n");
scanf("%d",&temp);
if(temp == 0){
break;
}else{
printf("请输入您的手机号码:\n");
scanf("%s",input);
if(check_huiyuan(infor,input) != NULL){
printf("会员卡享受7折优惠\n");
sum *= rate;
break;
}else{
printf("未查询到会员信息!请重新输入\n");
continue;
}
}
}
printf("您应付金额为:%.2lf\n",(double)sum);
printf("1\t点餐\n2\t结算\n3\t会员卡管理\n");
return 0;
}
struct VIP *check_huiyuan(struct VIP *infor,char *input) //检查会员信息是否存在
{
struct VIP *xinxi;
xinxi = infor;
while(xinxi != NULL){
if(strcmp(xinxi->tel,input) == 0){
return xinxi;
}
xinxi = xinxi->next;
}
return NULL;
}
/*-----会员管理函数区-----*/
int huiyuan()
{
printf("欢迎进入会员管理系统\n");
printf("请选择您需要的服务项目:\n");
printf("1\t会员信息录入\n2\t会员信息显示\n3\t会员卡注销\n");
printf("输入0返回上一级\n");
int temp = 0,flag = 1;
struct VIP *infor = NULL;
while(1){
scanf("%d",&temp);
switch(temp)
{
case 1:huiyuan_upload(&infor);break; //会员信息录入
case 2:huiyuan_print(infor);break; //会员信息打印
case 3:huiyuan_delete(infor) ;break; //会员信息注销
case 0:printf("1\t点餐\n2\t结算\n3\t会员卡管理\n");return 0;
default:printf("输入错误!请重新输入");continue;
}
}
}
void getInput(struct VIP *infor)
{
printf("请输入姓名:");
scanf("%s",infor->name);
printf("请输入手机号码:");
scanf("%s",infor->tel);
}
void huiyuan_upload(struct VIP **xinxi)
{
struct VIP *infor,*temp;
infor = (struct VIP *)malloc(sizeof(struct VIP));
if (infor == NULL){
printf("内存分配失败!");
exit(1);
}
getInput(infor);
if(*xinxi != NULL){
temp = *xinxi;
*xinxi = infor;
infor->next = temp;
}
else{
*xinxi = infor;
infor->next = NULL;
}
saveVIP(infor);
}
void saveVIP(struct VIP *xinxi)
{
FILE *fp;
struct VIP *infor = xinxi->next;
fp = fopen("huiyuan.txt","w");
if(fp == NULL){
printf("can't open file!\n");
exit(1);
}
while(infor != NULL){
fprintf(fp,"%s\t%s\n",infor->name,infor->tel);
infor = infor->next;
}
fclose(fp);
}
struct VIP *readVIP() //运行前把文件内容读取到电脑内存
{
struct VIP *infor = (struct VIP *)malloc(sizeof(struct VIP));
char temp1,temp2;
struct VIP *p,*q;
p = q = infor;
FILE *fp;
fp=fopen("huiyuan.txt","r");
if(fp == NULL){
printf("无法打开文件\n");
return NULL;
}
while(fscanf(fp,"huiyuan.txt","r") != EOF){
struct VIP *q = (struct VIP *)malloc(sizeof(struct VIP));
strcpy(q->name,temp1);
strcpy(q->tel ,temp2);
p = q;
}
p->next = NULL;
fclose(fp);
return infor;
}
void huiyuan_print(struct VIP *infor)
{
struct VIP *xinxi;
int num = 1;
xinxi = infor;
while(xinxi != NULL){
printf("Number %d:",num);
printf("姓名:%s",xinxi->name);
printf("手机号码:%s\n",xinxi->tel);
xinxi = xinxi->next;
num++;
}
}
void huiyuan_delete(struct VIP *infor)
{
struct VIP *xinxi,*temp;
char input;
printf("请输入需要删除的会员的手机号码:\n");
scanf("%s",input);
temp = infor;
xinxi = temp->next;
while(xinxi != NULL){
if(strcmp(xinxi->tel,input)==0){
temp->next = xinxi->next;
free(xinxi);
break;
}
temp = xinxi;
xinxi = xinxi->next;
}
}
"""
emmmm论坛怎么编辑markdown{:10_285:}
你可以看看我的学籍管理的源代码,原理和你差不多。本来如果手上有电脑就可以帮你程序调试看看的 糖水煮萝卜 发表于 2020-6-26 22:03
emmmm论坛怎么编辑markdown
MarkDown 还在测试{:10_277:}
按<> 发代码 永恒的蓝色梦想 发表于 2020-6-26 22:22
MarkDown 还在测试
按 发代码
嗯好的,下次一定{:10_323:} jhanker 发表于 2020-6-26 22:12
你可以看看我的学籍管理的源代码,原理和你差不多。本来如果手上有电脑就可以帮你程序调试看看的
感谢大佬!刚看了您的代码,感觉搬过来成本太高了,我可能只是需要一点点小改动{:10_278:} 糖水煮萝卜 发表于 2020-6-26 22:35
嗯好的,下次一定
别下次一定了,我连你代码写的啥都不知道 没有huiyuan.txt文件,你的代码也调试不了。看到的几点说一下吧。
1.struct VIP *readVIP() //运行前把文件内容读取到电脑内存
struct VIP *p,*q;
struct VIP *q = (struct VIP *)malloc(sizeof(struct VIP)); --》q = (struct VIP *)malloc(sizeof(struct VIP));
strcpy(q->name,temp1);
strcpy(q->tel ,temp2); -->>从文件中读取的数据赋值给temp1和temp2了吗
是不是应该有这样的语句
while(!feof(fp))
{
fscanf(fp, “%s\t%s\n”, temp1, temp2);
}
p = q; ---》p = p->next;
2.删除结点要判断两种情况
(1)尾结点
(2)非尾结点 chxchxkkk 发表于 2020-6-27 09:45
没有huiyuan.txt文件,你的代码也调试不了。看到的几点说一下吧。
1.struct VIP *readVIP() //运行前把文 ...
大佬,我刚改了一下,我自己新建一个huiyuan.txt是可以存入数据的(随便敲几条),但是有这样几个问题
1、最新的一组数据存不进去,必须要在输入一个才能把上一组存进去
2、回到主函数后再选择录入信息,txt里面的内容就被清空了
3、读取文件的时候的确没把数据赋值到链表里面
因为这个作业是我们课上自己展示,别的小问题已经无所谓了,就希望结算那里检查是不是会员的时候能读到会员信息,把后面几行跑完就行了。
能麻烦您帮忙改一下吗{:10_303:} 本帖最后由 jhanker 于 2020-6-28 08:41 编辑
看看下面的代码能不能运行
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*-----信息存储区-----*/
struct Caipin{
char cai;
int price;
}caipin={ //7种菜品
{"steak",50},{"lamb",30},{"bacon",25},{"chicken",30},
{"vegetable",15},{"meatball",20},{"lobster",100}
};
struct Zhushi{
char zhu;
int price;
}zhushi={ //5种主食
{"rice",5},{"cake",3},{"noodles",7},
{"jiaozi",20},{"bun",10}
};
struct Yinliao{
char yin;
int price;
}yinliao={ //5种饮料
{"juice",3},{"coca-cola",5},{"tea",20},
{"coffee",15},{"milk",7}
};
struct VIP{ //用链表形式保存会员信息
char name;
char tel;
struct VIP *next;
};
/*-----函数声明区-----*/
float diancan();
float choice_caipin();
float choice_zhushi();
float choice_yinliao();
int jiesuan(struct VIP *infor,float sum);
struct VIP *check_huiyuan(struct VIP *infor,char *input);
int huiyuan(struct VIP **infor);
void getInput(struct VIP *infor);
void huiyuan_upload(struct VIP **xinxi);
void huiyuan_print(struct VIP *infor);
void huiyuan_delete(struct VIP **infor);
void saveVIP(struct VIP *xinxi);
struct VIP *readVIP();
/*-----主函数区-----*/
int main()
{
struct VIP *infor;
infor = readVIP();
// saveVIP(infor);
printf("欢迎使用XX餐厅前台管理系统\n");
printf("请选择您需要的服务项目:\n");
printf("1\t点餐\n2\t结算\n3\t会员卡管理\n");
int temp=0;
float sum = 0;
while(1){
scanf("%d",&temp);
switch(temp)
{
case 1:sum = diancan();break; //进入点餐界面
case 2:jiesuan(infor,sum);break; //进入结算系统
case 3:huiyuan(&infor);break; //进入会员管理系统
default:printf("输入错误!请重新输入");
}
}
return 0;
}
/*-----点餐函数区-----*/
float diancan()
{
printf("欢迎点餐!\n");
printf("请选择:\n1\t菜品\n2\t主食\n3\t饮料\n0\t返回主菜单\n");
int temp;
float sum = 0;
while(1){
scanf("%d",&temp);
switch(temp)
{
case 1:
sum += choice_caipin();
printf("请选择:\n1\t菜品\n2\t主食\n3\t饮料\n0\t返回主菜单\n");
break; //调用菜品选择函数,并计算总价格
case 2:
sum += choice_zhushi();
printf("请选择:\n1\t菜品\n2\t主食\n3\t饮料\n0\t返回主菜单\n");
break; //调用主食选择函数,并计算总价格
case 3:
sum += choice_yinliao();
printf("请选择:\n1\t菜品\n2\t主食\n3\t饮料\n0\t返回主菜单\n");
break; //调用饮料选择函数,并计算总价格
case 0:printf("1\t点餐\n2\t结算\n3\t会员卡管理\n");return sum; //返回主菜单
default:printf("输入错误!请重新输入");break;
}
}
}
float choice_caipin()
{
printf("请选择菜品:\n");
for(int i=0;i<7;i++){
printf("%d\t%s\t\t%d\n",i+1,caipin.cai,caipin.price);
}
printf("输入0返回上一级\n");
int choice;
float sum_caipin = 0;
while(1){
scanf("%d",&choice);
if(choice == 0){
break;
}
for (int j=0;j<7;j++){
if(choice == j+1){
printf("%s已选择\n",caipin.cai);
sum_caipin += caipin.price;
}
}
}
return sum_caipin;
}
float choice_zhushi()
{
printf("请选择主食:\n");
for(int i=0;i<5;i++){
printf("%d\t%s\t\t%d\n",i+1,zhushi.zhu,zhushi.price);
}
printf("输入0返回上一级\n");
int choice;
float sum_zhushi = 0;
while(1){
scanf("%d",&choice);
if(choice == 0){
break;
}
for (int j=0;j<7;j++){
if(choice == j+1){
printf("%s已选择\n",zhushi.zhu);
sum_zhushi += zhushi.price;
}
}
}
return sum_zhushi;
}
float choice_yinliao()
{
printf("请选择主食:\n");
for(int i=0;i<5;i++){
printf("%d\t%s\t\t%d\n",i+1,yinliao.yin,yinliao.price);
}
printf("输入0返回上一级\n");
int choice;
float sum_yinliao = 0;
while(1){
scanf("%d",&choice);
if(choice == 0){
break;
}
for (int j=0;j<7;j++){
if(choice == j+1){
printf("%s已选择\n",yinliao.yin);
sum_yinliao += yinliao.price;
}
}
}
return sum_yinliao;
}
/*-----结算函数区-----*/
int jiesuan(struct VIP *infor,float sum)
{
printf("您本次消费 %.2f 元",sum);
int temp = 1;
float rate = 0.7;
// struct VIP *infor = NULL;
char input;
while(temp == 1){
printf("您是否有会员卡?\n");
printf("1\t有\n0\t没有\n");
scanf("%d",&temp);
if(temp == 0){
break;
}else{
printf("请输入您的手机号码:\n");
scanf("%s",input);
if(check_huiyuan(infor,input) != NULL){
printf("会员卡享受7折优惠\n");
sum *= rate;
break;
}else{
printf("未查询到会员信息!请重新输入\n");
continue;
}
}
}
printf("您应付金额为:%.2f\n",sum);
printf("1\t点餐\n2\t结算\n3\t会员卡管理\n");
return 0;
}
struct VIP *check_huiyuan(struct VIP *infor,char *input) //检查会员信息是否存在
{
struct VIP *xinxi;
xinxi = infor;
while(xinxi != NULL){
if(strcmp(xinxi->tel,input) == 0){
return xinxi;
}
xinxi = xinxi->next;
}
return NULL;
}
/*-----会员管理函数区-----*/
int huiyuan(struct VIP **infor)
{
printf("欢迎进入会员管理系统\n");
printf("请选择您需要的服务项目:\n");
printf("1\t会员信息录入\n2\t会员信息显示\n3\t会员卡注销\n");
printf("输入0返回上一级\n");
int temp = 0,flag = 1;
// struct VIP *infor = NULL;
while(1){
scanf("%d",&temp);
switch(temp)
{
case 1:huiyuan_upload(infor);break; //会员信息录入
case 2:huiyuan_print(*infor);break; //会员信息打印
case 3:huiyuan_delete(infor) ;break; //会员信息注销
case 0:printf("1\t点餐\n2\t结算\n3\t会员卡管理\n");return 0;
default:printf("输入错误!请重新输入");continue;
}
}
}
void getInput(struct VIP *infor)
{
printf("请输入姓名:");
scanf("%s",infor->name);
printf("请输入手机号码:");
scanf("%s",infor->tel);
infor->next=NULL;
}
void huiyuan_upload(struct VIP **xinxi)
{
struct VIP *infor,*temp;
infor = (struct VIP *)malloc(sizeof(struct VIP));
if (infor == NULL){
printf("内存分配失败!");
exit(1);
}
getInput(infor);
if(*xinxi != NULL){
temp = *xinxi;
*xinxi = infor;
infor->next = temp;
}
else{
*xinxi = infor;
infor->next = NULL;
}
saveVIP(*xinxi);
}
void saveVIP(struct VIP *xinxi)
{
FILE *fp;
struct VIP *infor = xinxi;
fp = fopen("huiyuan.txt","wb+");
if(fp == NULL){
printf("can't open file!\n");
exit(1);
}
if(infor != NULL){
//fprintf(fp,"%s\t%s\n",infor->name,infor->tel);
rewind(fp);
fwrite(infor,sizeof(struct VIP),1,fp);
while (infor->next!=NULL)
{
fwrite(infor->next,sizeof(struct VIP),1,fp);
infor = infor->next;
}
}
fclose(fp);
}
struct VIP *readVIP() //运行前把文件内容读取到电脑内存
{
struct VIP *p,*q,*infor = (struct VIP *)malloc(sizeof(struct VIP));
p = q = infor;
FILE *fp;
if ( (fp=fopen("huiyuan.txt", "rb+"))==NULL)
{
if ( (fp=fopen("huiyuan.txt", "wb+"))==NULL)
{
printf("无法创建或打开\"huiyuan.txt\"文件\n");
exit(0);
}
return NULL;
}
else
{
if (fread(infor,sizeof(struct VIP),1,fp)!=0)
{
q= (struct VIP*)malloc(sizeof(struct VIP));
while(fread(q,sizeof(struct VIP),1,fp)!=0)
{
p->next = q;
p = q;
q= (struct VIP*)malloc(sizeof(struct VIP));
}
p->next =NULL ;
}
else
{
infor=NULL;
}
fclose(fp);
return infor;
}
}
void huiyuan_print(struct VIP *infor)
{
struct VIP *xinxi;
int num = 1;
xinxi = infor;
while(xinxi != NULL){
printf("Number %d:",num);
printf("姓名:%s",xinxi->name);
printf("手机号码:%s\n",xinxi->tel);
xinxi = xinxi->next;
num++;
}
}
void huiyuan_delete(struct VIP **infor)
{
struct VIP *xinxi,*temp;
char input;
printf("请输入需要删除的会员的手机号码:\n");
scanf("%s",input);
temp = *infor;
xinxi = temp;
while(xinxi != NULL){
if(strcmp(xinxi->tel,input)==0){
if (xinxi==*infor)
{
*infor=(*infor)->next;
free(xinxi);
break;
}
else
{
temp->next = xinxi->next;
free(xinxi);
break;
}
}
temp = xinxi;
xinxi = xinxi->next;
}
saveVIP(*infor);
}
由于一边修改一边调试,没来得及和你的原来代码比较。麻烦你自己区别一下,主要是在读取,保存文件,删除这几个代码处有改动 本帖最后由 jhanker 于 2020-6-28 08:39 编辑
糖水煮萝卜 发表于 2020-6-27 15:22
大佬,我刚改了一下,我自己新建一个huiyuan.txt是可以存入数据的(随便敲几条),但是有这样几个问题
1 ...
自己调试看看上面代码是否可行?如果huiyuan.txt文件没有,程序可以自动建立 jhanker 发表于 2020-6-28 02:14
看看下面的代码能不能运行
不好意思大佬,昨天事情多没及时看。代码完美运行了,实在太感谢您了。 糖水煮萝卜 发表于 2020-6-28 09:55
不好意思大佬,昨天事情多没及时看。代码完美运行了,实在太感谢您了。
你自己把代码对照一下看看,我也好久没用C语言了,特别是有关文件操作的函数是临时查看函数原型资料的,其实用fprintf fscanf可能会好一些。而且链表也不太熟练了。昨天刚好有电脑,所以就练练手 糖水煮萝卜 发表于 2020-6-28 09:55
不好意思大佬,昨天事情多没及时看。代码完美运行了,实在太感谢您了。
我不是大佬,对于C语言也算初学者。通过修改你的代码,感觉自己有两个地方是偷懒了,真正写大型程序估计不能这样做。
1.添加记录,一般是在链表尾部加记录的,为了方便尾部添加记录,可以增加一个指针变量让它永远指在链表的尾部,可以设成全局变量也可以设成main函数的局部变量
2.写文件的时候也一样,在增加记录时,可以直接在文件尾追加内容 糖水煮萝卜 发表于 2020-6-27 15:22
大佬,我刚改了一下,我自己新建一个huiyuan.txt是可以存入数据的(随便敲几条),但是有这样几个问题
1 ...
同时我也发现,你的问题主要出在一下几个方面:
1.变量的作用域没有把握好
2.函数参数的传递实质是值传递,没有认识准确
由于上述两点,造成回到主函数就清空了特别要注意如果在主函数中调用其他函数,如果要在被调用函数中修改主函数变量内容需要用高一级的指针变量 jhanker 发表于 2020-6-28 10:15
同时我也发现,你的问题主要出在一下几个方面:
1.变量的作用域没有把握好
2.函数参数的传递实质是值传 ...
好的,万分感谢!C语言这边我刚刚入门,对很多概念的理解还没到位,实际使用的时候出了问题也看不出来,更不要说弄清楚原理并改正。再次感谢您! 糖水煮萝卜 发表于 2020-6-29 10:16
好的,万分感谢!C语言这边我刚刚入门,对很多概念的理解还没到位,实际使用的时候出了问题也看不出来, ...
不谢,我也算新手
页:
[1]