首页 > 代码库 > C语言复习——指针 链表 与 文件操作
C语言复习——指针 链表 与 文件操作
刚刚进入大二,准备开始学习C++,对大一所学的C语言一次练习,正好也是赶上老师布置的任务,用C语言写一个 销售管理系统 ,就尽可能的把所学的都用上,也就是结构,指针,文件操作,还有数据结构,本次加入了链表。
用两个函数 Load_LinkList() 和 Save_LinkList() 让链表与文件操作结合,除了打印函数,其他都是在内存中操作链表,这样写更有条理,在创建链表时没有采用书上的用一个中间变量引导,并插入到结点前面,而是直接在链表尾的next申请内存,便于理解,操作也方便。
/*首先是文件包含,这里就不使用 ifndef 那样常规写一个头文件*/#include <stdio.h>#include <string.h>#include <windows.h>#include <stdlib.h>#include <conio.h>
/*接下来就是结构体*//*每一种商品对应一个结点,用链表连接起来,统一写入文件,或者从文件中读取*/typedef struct commodity{ int data; //头结点data统计个数,其余为商品编号 char name[20]; //名称 double price; //价格 int count; //数量 double sum; //总计,头结点sum为所有商品总计 struct commodity *next;} *LinkList, LNode;
/*定义全局变量,方便使用*//*链表头指针*/LinkList H = NULL;/*文件指针*/FILE *fp = NULL;
/*函数声明*//***************显示函数****************///欢迎界面void welcome();//显示菜单void menu();
//打印表格头void printf_header();
//显示单个结点信息void printf_linklist_info(LinkList pTemp);//延时函数void delay();/***********链表文件操作函数*****************///从文件中读取到链表中void Load_LinkList(LinkList H);//将链表保存到文件中void Save_LinkList(LinkList H);/***************链表函数**********************///建立头结点void Creat_LinkList();//添加结点到链表尾部LinkList Add_LinkList(LinkList H);//输入结点数据void Scanf_LinkList(LinkList pTemp);//找到符合要求的结点的前驱LinkList Find_LinkList_Pos(LinkList H,int index);//找到符合要求的结点的地址LinkList Find_LinkList_Val(LinkList H, char *name);//删除指定结点void Del_LinkList(LinkList H, char *name);//修改结点内容void Modify_LinkList(LinkList H, int index, int data);//顺序输出void Printf_LinkList(LinkList H);//释放内存void Free_LinkList(LinkList H);
/*main函数,没什么说的,除了getch函数用的时候会方便一些*/int main(){ LinkList pTemp = NULL; char name[20] = {0}; system("color A"); //welcome(); Creat_LinkList(); Load_LinkList(H); while(1) { system("cls"); menu(); switch(getch()) { case ‘1‘: pTemp = Add_LinkList(H); Scanf_LinkList(pTemp); getch(); break; case ‘2‘: printf_header(); Printf_LinkList(H); getch(); break; case ‘3‘: printf("\n输入名称查找:"); scanf("%s", name); pTemp = Find_LinkList_Val(H, name); printf_linklist_info(pTemp); getch(); break; case ‘4‘: printf("\n请先输入名称查找:"); scanf("%s", name); pTemp = Find_LinkList_Val(H, name); Scanf_LinkList(pTemp); getch(); break; case ‘5‘: printf("\n请先输入名称查找:"); scanf("%s", name); Del_LinkList(H, name); getch(); break; case ‘6‘: Save_LinkList(H); printf("\n成功保存%d条信息!\n", H->data); getch(); break; case ‘0‘: printf("\n欢迎下次使用!\n"); exit(0); default : printf("错误输入!"); getch(); } } return 0;}
////////////////////下面是显示函数实现内容
/*欢迎界面,其实不要也可以*/void welcome(){ int i; for(i=1 ; i<=100 ; i++) { printf("*******************欢迎使用本系统*************************"); printf("\n\n\n\n\n\n\n"); printf(" 加载中"); printf("...\n"); printf(" %3d%%\n",i); printf("**********************************************************"); system("cls"); } return ;}
/*菜单函数*/void menu(){ system("cls"); printf(" 欢迎进入本系统 \n"); printf("\n"); printf("-------------------------------------------------------------------\n"); printf("| 1 添加商品 |\n"); printf("| 2 显示商品 |\n"); printf("| 3 查找商品 |\n"); printf("| 4 修改商品 |\n"); printf("| 5 删除商品 |\n"); printf("| 6 保存修改 |\n"); printf("| 0 退出系统 |\n"); printf("-------------------------------------------------------------------\n"); printf(" 提示:退出前请先保存!"); printf("\nchoose(0-8):");}
/*以表格的形式打印所有商品信息*/void printf_header(){ system("cls"); printf("-------------------------您的所有库存-------------------------------------\n"); printf("| 编号 | 名称 | 价格 | 数量 | 总计 |\n"); printf("|----------|---------------|---------------|----------------|------------|\n");}
/*显示单个结点信息*/void printf_linklist_info(LinkList pTemp){ if(pTemp == NULL) { return ; } printf_header(); pTemp->sum = pTemp->price * pTemp->count; printf("|%10d|%15s| %lf |%20d| %lf |\n",pTemp->data, pTemp->name, pTemp->price, pTemp->count, pTemp->sum); printf("|----------|---------------|---------------|----------------|------------|\n"); return ;}
/*延时函数,写完了发现我一直用的是getch等待按键*/void delay(){ long int i,j; for(i=500000 ; i>0 ; i--) { for(j=0 ; j<=2000 ; j++); }}
/*创建头结点*/void Creat_LinkList(){ H = (LinkList)malloc(sizeof(LNode)); if(H) { H->next = NULL; H->data = http://www.mamicode.com/0; } return ;}
/*添加结点,这里是直接用最后一个节点的next申请内存*/LinkList Add_LinkList(LinkList H){ LinkList q = H; while(q->next != NULL) q = q->next; q->next = (LinkList)malloc(sizeof(LNode)); q->next->sum = 0; q->next->next = NULL; H->data++; return q->next;}
/*用于添加结点时输入结点信息,或者修改时输入*/void Scanf_LinkList(LinkList pTemp){ if(pTemp == NULL) { return ; } printf("\n输入编号:"); scanf("%d", &pTemp->data); printf("输入名称:"); scanf("%s", pTemp->name); printf("输入价格:"); scanf("%lf", &pTemp->price); printf("输入数量:"); scanf("%d", &pTemp->count); pTemp->sum = pTemp->price * pTemp->count;}
/*从文件中读取并加载到链表中,和Save函数一样,是最关键的两个函数*/void Load_LinkList(LinkList H){ LinkList p = NULL, pTemp = NULL; pTemp = (LinkList)malloc(sizeof(LNode)); pTemp->next = NULL; fp = fopen("D:/a.txt", "rb"); while(1) { /*这里用一个中间结点,临时储存,fread读一次才能决定是否添加结点,直接用p添加结点会错误,本身就是空文件时会多出一个结点,存的垃圾值,而fread必须有一块内存才能读*/ if((fread(pTemp, sizeof(LNode), 1, fp)) != 0) { p = Add_LinkList(H); p->data = http://www.mamicode.com/pTemp->data; strcpy(p->name, pTemp->name); p->price = pTemp->price; p->count = pTemp->count; H->data++; } else break; } free(pTemp); fclose(fp); return ;}
/*将链表保存到文件中*/void Save_LinkList(LinkList H){ LinkList p = H->next; if(p == NULL) { /*这里是清空一下,假如链表中保存的有数据,调用删除完之后,不能用fwrite,只是这种情况下用wb清空文件*/ fp = fopen("D:/a.txt", "wb"); H->data = http://www.mamicode.com/0; fclose(fp); getch(); return ; } fp = fopen("D:/a.txt", "wb"); while(p != NULL) { fwrite(p, sizeof(LNode), 1, fp); p = p->next; } fclose(fp); return ;}
///////////////接下来的函数就是只在内存里面操作链表
/*通过位置查找,返回结点 前驱结点 地址,计划是有这个查找的,后来写菜单也不想用了,就放这里没动过*/LinkList Find_LinkList_Pos(LinkList H,int index){ LinkList p = H; index--; while(index--) { p = p->next; } return p;}
/*通过字符串匹配查找,返回结点地址*/LinkList Find_LinkList_Val(LinkList H, char *name){ LinkList p = H; while(strcmp(p->name, name) != 0 && p->next != NULL) { p = p->next; } if(p->next == NULL) { printf("没有此商品!"); return NULL; getch(); } return p;}
/*删除一个结点,pre是前驱结点,p是要找的结点*/void Del_LinkList(LinkList H, char *name){ int flag = 0; LinkList p = H->next, pre = H; while(p != NULL) { if(strcmp(p->name, name) == 0) { flag = 1; break; } pre = p; p = p->next; } if(flag == 0) { printf("没有此商品!\n"); return ; } p = pre->next; pre->next = p->next; free(p); return ;}
/*修改结点信息,也是也可以实现的,和Find_LinkList_Pos()一样,没有用过*/void Modify_LinkList(LinkList H, int index, int data){ LinkList p = Find_LinkList_Pos(H, index+1); if(p) p->data =http://www.mamicode.com/ data; return ;}
/*顺序输出,表格没有对太齐,应该用 %xd 这样的,后来也不想改了*/void Printf_LinkList(LinkList H){ LinkList p = NULL; p = H->next; if(p == NULL) { printf("当前没有任何商品!"); getch(); return ; } while(p != NULL) { p->sum = p->price * p->count; printf("|%10d|%15s| %lf | %15d | %lf |\n",p->data, p->name, p->price, p->count, p->sum); printf("-------------------------------------------------------------------------------\n"); p = p->next; } printf(" %lf\n", H->sum); return ;}
/*内存总是要释放的*/void Free_LinkList(LinkList H){ LinkList pre = NULL, p = H->next; while(pre != NULL) { pre = p->next; free(p); p = p->next; } H->next = NULL; return ;}
C语言复习——指针 链表 与 文件操作
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。