qq_58480330 2021-06-10 08:50 采纳率: 0%
浏览 48
已结题

C语言程序小白,初次做大于500行代码,诸多问题,希望解答?

#include <stdio.h>
#include <malloc.h> 
#include <string.h> 
#include <stdlib.h> 


typedef struct hapen
{
	int year;  //年
	int month;  //月
	int num;  //数量
}dat;


typedef struct project  //物品基础信息
{
	char name[50]; //物品名称
	int price; //物品价格

}pro;


typedef union ddoing   //进、出货性质数据
{
	dat in;    //进货数据
	dat out;   //售货数据
}ndata;


typedef struct dddoing   //进出货数据
{
	char kind;    //“i”为进货;“o”为售货
	pro prodata;  //物品信息
	ndata rdata;  //进\出货性质数据
}justdo;

typedef union kinds   //基础信息或流动数据信息共用体
{
	pro data;    //物品基础信息
	justdo tdata;  //流动数据

}choose;

typedef struct LNode
{
	char kinds;// 选择基础信息或流动数据信息  “A”为基础信息,“C”为流动数据
	choose doit;
	struct LNode* next;
}LinkList;


char nam[50];  //物品名称
int pric;  //物品价格
int yea;   //年
int mont;  //月
int nu;   //数量
char kin;  //进出货情况
char ki;   //选择基础信息或流动数据信息  “A”为基础信息,“C”为流动数据


/*void InitList(LinkList* L)  //初始化链表
{
	L = (LinkList*)malloc(sizeof(LinkList));
	L->next = NULL;
}
*/

void ListInsert(LinkList* L, LinkList* p)//插入新的节点  
{
	LinkList* q = NULL;
	q = L;
	p->next = q->next;
	q->next = p;
}



void addproject(LinkList* L)  //增加新物品信息
{
	printf("请输入物品信息");
	LinkList* q = L->next;
	while (q != NULL)//移动到链表结尾
	{
		q = q->next;
	}
	if (q == NULL)
	{
		LinkList* p;
		p = (LinkList*)malloc(sizeof(LinkList));
		p->next = NULL;
		printf("请选择你要添加的方式(“A”为基础信息,“B”为流动数据):\n");
		scanf("%c", &ki);
		if ('C' == ki)                                             //进行流动数据操作
		{
			p->kinds, ki;
			printf("请进货出货最频繁也限制在每个月只记录一次\n");
			printf("物品名称(不可有空格):\n");
			scanf("%s", nam);
			strcpy(p->doit.tdata.prodata.name, nam);

			printf("物品价格/元:\n");
			scanf("%d", &pric);
			p->doit.tdata.prodata.price = pric;

			printf("信息情况(“i”为进货;“o”为售货):\n");
			scanf("%c", kin);
			p->doit.tdata.kind = kin;
			if (kin == 'i')                 //进货操作
			{
				printf("输入进货年:\n");
				scanf("%d", yea);
				p->doit.tdata.rdata.in.year = yea;

				printf("输入进货月:\n");
				scanf("%d", mont);
				p->doit.tdata.rdata.in.month = mont;

				printf("输入进货数量:\n");
				scanf("%d", nu);
				p->doit.tdata.rdata.in.num = nu;

			}
			if (kin == 'o')               //售货操作
			{
				printf("输入售货年:\n");
				scanf("%d", yea);
				p->doit.tdata.rdata.out.year = yea;

				printf("输入售货月:\n");
				scanf("%d", mont);
				p->doit.tdata.rdata.out.month = mont;

				printf("输入售货数量:\n");
				scanf("%d", nu);
				p->doit.tdata.rdata.out.num = nu;

			}
			else
			{
				printf("输入错误(“I”为进货;“O”为售货),请从头操作\n");
			}
		}
		if ('A' == ki)                 //进行基础信息操作
		{
			p->kinds = ki;
			printf("开始添加物品基础信息\n");
			printf("物品名称(不可有空格):\n");
			scanf("%s", nam);
			strcpy(p->doit.data.name, nam);

			printf("物品价格/元:\n");
			scanf("%d", &pric);
			p->doit.data.price = pric;

		}
		else
		{
			printf("输入错误(“A”为基础信息,“C”为流动数据),请从头操作\n");
		}
		ListInsert(L, p);
	}
}


void deletedata(LinkList* L)//删除数据
{
	if (L->next = NULL)
	{
		printf("还没有数据信息,请先增加物品数据信息\n");
		return;
	}
	LinkList* p, * pre;
	pre = L;
	p = pre->next;
	int judge = 0;
	printf("请输入你想删除的数据类型( “A”为基础信息,“C”为流动数据):\n");
	scanf("%c", &ki);
	if (ki == 'A')
	{
		printf("请输入你想删除的物品名称:\n");
		scanf("%s", nam);
		while (p != NULL)
		{
			if (0 == strcmp(p->doit.data.name, nam))
			{
				judge = 1;
				pre->next = p->next;
				free(p);
				printf("删除基本物品数据成功\n");
				break;
			}
			pre = p;
			if (p != NULL)
				p = p->next;
		}
		if (judge == 0)
			printf("这个物品信息不存在\n");
	}
	if (ki == 'C')
	{
		printf("请输入你想删除的信息情况(“i”为进货;“o”为售货):\n");
		scanf("%c", &kin);
		printf("请输入你想删除买卖情况数据的物品名称:\n");
		scanf("%s", nam);
		printf("请输入你想删除买卖物品的时间信息\n");
		printf("年:\n");
		scanf("%d", yea);
		printf("月:\n");
		scanf("%d", mont);
		while (p != NULL)
		{
			if (kin == 'I')
			{
				if ((p->doit.tdata.kind = kin) && (0 == strcmp(p->doit.tdata.prodata.name, nam)) && (p->doit.tdata.rdata.in.year = yea) && (p->doit.tdata.rdata.in.month = mont))
				{
					judge = 1;
					pre->next = p->next;
					free(p);
					printf("删除进货物品数据成功\n");
					break;
				}
				pre = p;
				p = p->next;
			}
			if (kin == 'O')
			{
				if ((p->doit.tdata.kind = kin) && (0 == strcmp(p->doit.tdata.prodata.name, nam)) && (p->doit.tdata.rdata.out.year = yea) && (p->doit.tdata.rdata.out.month = mont))
				{
					judge = 1;
					pre->next = p->next;
					free(p);
					printf("删除售货物品数据成功\n");
					break;
				}
				pre = p;
				p = p->next;
			}
			else
			{
				printf("输入错误,请从头开始\n");
				break;

			}

		}
		if (judge == 0)
			printf("这个信息不存在\n");

	}
	else
	{
		printf("输入错误,请从头开始\n");
	}

}


int ListLength(LinkList* L)//求链表长度
{
	int n = 0;
	LinkList* p, * q;
	p = L;
	do
	{
		p = p->next;
		printf("1");
		n++;
		
	} while (p!= NULL);
	return n;
}


void finddata(LinkList* L)  //按照名称查找并输出该物品信息
{
	printf("请输入你要查询的物品名称:\n");
	scanf("%s", nam);
	LinkList* P;
	P = L->next;
	while (P != NULL)
	{
		if (('A' == P->kinds) && (0 == strcmp(P->doit.data.name, nam)))
		{
			printf("名称:%s\t价格%d元/个\n", P->doit.data.name, P->doit.data.price);
			break;
		}
		P = P->next;
	}
	if (P == NULL)
		printf("该物品不存在\n");
}


void displaypro(LinkList* L)//列出所有物品基础信息
{
	LinkList* q = L->next;
	if (q == NULL)
	{
		printf("还没有物品基础信息,请增加物品基础信息\n");
		return;
	}
	while (q != NULL)
	{
		if (('A' == q->kinds) && (0 == strcmp(q->doit.data.name, nam)));
		{
			printf("名称:%s\t价格%d元/个\n", q->doit.data.name, q->doit.data.price);
		}
		q = q->next;
	}
	printf("列出结束\n");
}


void displayin(LinkList* L)//列出所有进货物品信息
{
	LinkList* q = L->next;
	if (q == NULL)
	{
		printf("还没有物品进货信息,请增加物品进货信息\n");
		return;
	}
	while (q != NULL)
	{
		printf("有");
		if (('C' == q->kinds) && ('i' == q->doit.tdata.kind))
		{
			printf("名称:%s\t价格%d元/个\t购进时间:%d年%d月\t购进个数:%d个\n", q->doit.tdata.prodata.name, q->doit.tdata.prodata.price, q->doit.tdata.rdata.in.year, q->doit.tdata.rdata.in.month, q->doit.tdata.rdata.in.num);
		}
		q = q->next;
	}
}


void displayout(LinkList* L)//列出所有售货物品信息
{
	LinkList* q = L->next;
	if (q == NULL)
	{
		printf("还没有物品基础信息,请增加物品基础信息\n");
		return;
	}
	while (q != NULL)
	{
		if (('C' == q->kinds) && ('o' == q->doit.tdata.kind))
		{
			printf("名称:%s\t价格%d元/个\t购进时间:%d年%d月\t购进个数:%d个\n", q->doit.tdata.prodata.name, q->doit.tdata.prodata.price, q->doit.tdata.rdata.out.year, q->doit.tdata.rdata.out.month, q->doit.tdata.rdata.out.num);
		}
		q = q->next;
	}
}


void savedata(LinkList* L)//保存至文件夹
{
	FILE* fp;
	LinkList* p = L->next;
	if ((fp = fopen("data.txt", "w")) == NULL)// 以可写的方式打开当前目录下的.txt  
	{
		printf("不能打开此文件,请按任意键退出\n");
		exit(1);  //异常退出
	}
	while (p != NULL)
	{
		if ('A' == p->kinds)
		{
			fprintf(fp, "%c %s %d\n", p->kinds, p->doit.data.name, p->doit.data.price);
			p = p->next;
			printf("保存基本信息成功\n");
		}
		else if ('C' == p->kinds)
		{
			if ('i' == p->doit.tdata.kind)
			{
				fprintf(fp, "%c %c %s %d %d %d %d", p->kinds, p->doit.tdata.kind, p->doit.tdata.prodata.name, p->doit.tdata.prodata.price, p->doit.tdata.rdata.in.year, p->doit.tdata.rdata.in.month, p->doit.tdata.rdata.in.num);
				p = p->next;
				printf("保存进货信息成功\n");
			}
			if ('o' == p->doit.tdata.kind)
			{
				fprintf(fp, "%c %c %s %d %d %d %d", p->kinds, p->doit.tdata.kind, p->doit.tdata.prodata.name, p->doit.tdata.prodata.price, p->doit.tdata.rdata.out.year, p->doit.tdata.rdata.out.month, p->doit.tdata.rdata.out.num);
				p = p->next;
				printf("保存售货信息成功\n");
			}
		}
	}
	fclose(fp);
}


void readdata(LinkList* L)//读取文件中的信息拷贝到程序中
{
	FILE* fp;
	fp = fopen("data.txt", "r");//以只读方式打开文件夹
	if (fp == NULL)
	{
		printf("文件不存在\n");
		exit(0);            //终止程序
	}
	while (!feof(fp))
	{
		LinkList* n = (LinkList*)malloc(sizeof(LinkList));
		fscanf(fp, "%c", &ki);
		if (ki == 'A')
		{
			fscanf(fp, "%s %d", nam, &pric);
			n->kinds = ki;
			strcpy(n->doit.data.name, nam);
			n->doit.data.price = pric;
			ListInsert(L, n);//插入新的节点  
			n = n->next;
		}
		if (ki == 'C')
		{
			fscanf(fp, "%c", &kin);
			if (kin == 'i')
			{
				fscanf(fp, "%s %d %d %d %d", nam, &pric, &yea, &mont, &nu);
				n->kinds = ki;
				n->doit.tdata.kind = kin;
				strcpy(n->doit.tdata.prodata.name, nam);
				n->doit.tdata.prodata.price = pric;
				n->doit.tdata.rdata.in.year = yea;
				n->doit.tdata.rdata.in.month = mont;
				n->doit.tdata.rdata.in.num = nu;
				ListInsert(L, n);//插入新的节点  
				n = n->next;
			}
			if (kin == 'o')
			{
				fscanf(fp, "%s %d %d %d %d", nam, &pric, &yea, &mont, &nu);
				n->kinds = ki;
				n->doit.tdata.kind = kin;
				strcpy(n->doit.tdata.prodata.name, nam);
				n->doit.tdata.prodata.price = pric;
				n->doit.tdata.rdata.out.year = yea;
				n->doit.tdata.rdata.out.month = mont;
				n->doit.tdata.rdata.out.num = nu;
				ListInsert(L, n);//插入新的节点  
				n = n->next;
			}
		}
	}
	fclose(fp);//关闭文件
	printf("录入完毕\n");
}


void freeList(LinkList* L)  //释放分配的空间
{
	LinkList* p, * q;
	int n = 0;
	p = L;
	q = L->next;
	while (n < ListLength(L))
	{
		n++;
		free(p);
		p = q;
		if (p != NULL)
			q = p->next;
	}
	printf("已释放\n");
}




int main()
{
	LinkList* L;
	L = (LinkList*)malloc(sizeof(LinkList));
		L->next = NULL;
	readdata(L);
	int i;

	system("cls");  //清新页面
	printf(" =====================================================\n");
	printf("--------------- 菜————单 -------------------------\n");
	printf(" -----------------------------------------------------\n");
	printf("|#                                                  #|\n");
	printf("|#欢迎使用商店货物买卖系统第一版                    #|\n");
	printf("|#(由于技术原因只能操作不会损坏的商品销售)        #|\n");
	printf("|#                                                  #|\n");
	printf("|#                                                  #|\n");
	printf(" =====================================================\n");
	printf("----------------商品基础信息--------------------------\n");
	printf(" -----------------------------------------------------\n");
	printf("|#             (包含名称、价格)                   #|\n");
	printf("|#                                                  #|\n");
	printf("|#               1.查询物品信息                     #|\n");
	printf("|#                                                  #|\n");
	printf("|#               2.删除物品信息                     #|\n");
	printf("|#                                                  #|\n");
	printf("|#               3.添加物品信息                     #|\n");
	printf("|#                                                  #|\n");
	printf("|#               4.列出全部物品清单                 #|\n");
	printf("|#                                                  #|\n");
	printf("|#--------------------------------------------------#|\n");
	printf(" =====================================================\n");
	printf("--------------------货物流动情况----------------------\n");
	printf(" -----------------------------------------------------\n");
	printf("|#                                                  #|\n");
	printf("|#               5.显示总入物品                     #|\n");
	printf("|#       (包含名称、价格、更新年月、数量)         #|\n");
	printf("|#                                                  #|\n");
	printf("|#               6.显示售出物品                     #|\n");
	printf("|#       (包含名称、价格、售出年月、数量)         #|\n");
	printf("|#                                                  #|\n");
	printf("|#               7.保存                             #|\n");
	printf("|#--------------------------------------------------#|\n");
	printf("|#               0.退出                             #|\n");
	printf("------------------------------------------------------\n");
	do {
		printf("选择工作:");
		scanf("%d", &i);
		switch (i)
		{
		case 1:
			finddata(L);
			break;
		case 2:
			deletedata(L);
			break;
		case 3:
			addproject(L);
			break;
		case 4:
			displaypro(L);
			break;
		case 5:
			displayin(L);
			break;
		case 6:
			displayout(L);
			break;
		case 7:
			savedata(L);
			break;
		case 0:
			break;
		default:
			printf("请输入正确的选择\n");
			break;
		}


	} while (i);
	printf("程序已退出!");
	freeList(L);
	return 0;
}

(数据文件没有放在这里,那个没有代表意义)

我用的是vs2019,也关掉了SDL检查,但是scanf(“%c”,&ki)这段语句和fscanf(“%c”,&ki)这段语句在文件中检测到‘C’时还是运行不了,我猜测它运行不了的原因有二第一个就是我把addproject拆成两段,一段是只输入基础信息的函数,一段是输入流动数据的函数,但是发现前者可以正确运行,后者到了scanf(“%c”,&kin)的时候报错说出现间断;其二就是我在数据文件中手动输入几段进出货的数据,但是在后面操作输出进出货数据时候都没有结果,于是我在显示进货函数循环中写下printf(“1”)但是只执行了基础信息个数次数,说明链表中只有基础信息,流动信息没有加入进去,结合第一个原因,我认为是fscanf的原因。这是一个问题,还有就是在运行freeList这个函数的时候这个问题。

于是我回到主函数看以下尾节点是否赋了NULL值结果发现:

这里是这样的。所以现在不知道怎么改正。

  • 写回答

3条回答 默认 最新

  • CSDN专家-link 2021-06-10 08:59
    关注

    如果代码都是自己写的话,挺好了

    do...while不太好,要用while,传入的L为空怎么办呢,会崩溃的

    另外,在scanf("%c",&ki)等读入单个字符的语句后,最好加一句getchar(),否则如果连续读入%c的话,第二个%c会自动读入回车符的,你的代码里有这种情况

    评论

报告相同问题?

悬赏问题

  • ¥100 有人会搭建GPT-J-6B框架吗?有偿
  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名