对于链式存储来说,它的好处就是每一个元素可以存储在任意位置,只需要通过指针将相互直接关联的元素链接起来就好。代码部分有信息的写入,信息的读入信息的保存,当然,我最开始一直在链表的初始化犯迷糊,最后经人指点。也成功解决了这个问题,下面代码是关于这个问题的呈现。
关于程序的准备如下:
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
typedef struct {
char name[20];
char leibie[20];
int number;
int price;
}restaurant;
typedef struct listnode {
restaurant data;//数据域
struct listnode* next;//指针域
}listnode, * linklist;
linklist l = NULL; //菜单列表
linklist l2 = NULL; //已售出列表即销售额
FILE* fp, * d;
char c[1000];
char m[20] = "xiaoshou.txt"; //尽量不要中文文件名 这个文件理论上是在当前目录下
//但是实际是在项目的debug文件目录下。如果找不到,可换成绝对路径
char file[20] = "membership";
char g[20] = "sk";
char filename[20] = "das";
void InitList(linklist& l) {
l = (listnode*)malloc(sizeof(listnode));
l->next = NULL;
}
int menu();
之后就是文件的创建,读取,保存,当然我觉的显示这部分没有什么必要,可以在VS中的文件直接查看,但我还是带上这部分了。
关于第一个文件信息的录入如下:
void openfile() {
listnode* g, * h;
h = l;
fp = fopen(filename, "a+");
while (true) {
g = (listnode*)malloc(sizeof(listnode));
g->next = NULL;
if (fscanf(fp, "%d\t%s\t%s\t%d", &g->data.number, g->data.name, g->data.leibie, &g->data.price) == EOF) {
free(g);
break;
}
h->next = g;
h = h->next;
}
fclose(fp);
}
void add_message() {
cout << "\n\t\t\t正在添加菜品信息\n";
int x = 1;
linklist g, h;
while (x) {
g = (listnode*)malloc(sizeof(listnode)); g->next = NULL;
printf("\t\t\t正在添加菜品的信息\n");
cout << "\t\t\t请输入菜号:";
cin >> g->data.number;
while (1) {
h = l->next;
while (h != NULL) {
if (h->data.number == g->data.number) {
cout << "\t\t\t菜号重复,重新输入\n";
cin >> g->data.number;
break;
}
h = h->next;
}
if (h == NULL) break;
}
cout << "\t\t\t请输入菜名:";
cin >> g->data.name;
cout << "\t\t\t请输入类别:";
cin >> g->data.leibie;
cout << "\t\t\t请输入价格:";
cin >> g->data.price;
cout << "\n";
if (l->next == NULL) {
l->next = g;
}
else {
h = l;
while (h->next != NULL)
{
h = h->next;
if (h->next != NULL && g->data.number >= h->data.number && g->data.number <= h->next->data.number) {
g->next = h->next;
h->next = g;
break;
}
else if (h->next == NULL) {
break;
}
}
h->next = g;
}
cout << "\t\t\t继续添加输入1,结束输入0:";
cin >> x;
}
}
void print_message() {
cout << "\n\n\t\t\t显示菜品信息\n";
linklist g;
g = l->next;
cout << "\t\t\t菜号\t菜名\t\t类别\t价格\n";
if (g == NULL) {
cout << "\t\t\t没有数据!";
system("pause");
return;
}
while (g != NULL) {
printf("\t\t\t%d\t%s\t%s\t%d\n", g->data.number, g->data.name, g->data.leibie, g->data.price);
g = g->next;
}
system("pause");
}
void save_file() {
linklist h = l->next;
if ((fp = fopen(filename, "w")) == NULL) {
cout << "\t\t\t打开文件失败,";
system("pause");
return;
}
else {
while (h != NULL) {
fprintf(fp, "%d\t%s\t%s\t%d\n", h->data.number, h->data.name, h->data.leibie, h->data.price);
h = h->next;
}
}
fclose(fp);
cout << "\t\t\t保存成功,";
system("pause");
menu();
}
而这一部分就是这个问题的关键,对写入文件信息的查找并读入另一个文件,当时我的思想是,当查找到这个文件时,把这个节点的信息赋值给另一个链表的节点,但因为这个节点并没有初始化,所以这是行不通的,所以在准备工作中,解决了具体的问题,而其中的保存,创建,读取文件从上面的代码就可以了解,主要看diancai()这个区域的代码。具体的代码如下:
void xiaoshou() {
listnode* p, * q;
q = l2;
if ((d = fopen(m, "a+")) == NULL) {
cout << "\t\t\t打开文件失败,";
system("pause");
return;
}
while (true) {
p = (listnode*)malloc(sizeof(listnode));
if (fscanf(d, "%d\t%s\t%s\t%d", &p->data.number, p->data.name, p->data.leibie, &p->data.price) == EOF) {//
free(p);
break;
}
p->next = NULL;
q->next = p;
q = q->next;
}
fclose(d);
}
void diancai() {
cout << "\n\t\t\t请添加你选择的菜品信息\n";
int x = 1;
linklist p, q;
while (x) {
int s;
cout << "\t\t\t请输入菜号:";
cin >> s;
linklist g;
g = l->next;
if (g == NULL) {
cout << "\t\t\t没有菜品";
system("pause");
return;
}
while (g != NULL) {
if (g->data.number == s) {
cout << "\t\t\t菜号\t菜名\t类别\t价格\n";
printf("\t\t\t%d\t%s\t%s\t%d\n", g->data.number, g->data.name, g->data.leibie, g->data.price);
break;
}
else g = g->next;
}
if (g == NULL) cout << "\t\t\t没有菜品";
else {
InitList(p); //p需要存储卖出的菜,所以需要初始化开辟存储空间
p = g;
p->next = NULL;
q = l2; //q自己不存储信息,它只是指向某一个已存储信息的节点所以不初始化
while (q->next != NULL) q = q->next;
q->next = p;
}
cout << "\n\t\t\t继续添加输入1,结束输入0:";
cin >> x;
}
}
void xiaoshufile() {
linklist q = l2->next;
if ((d = fopen(m, "w")) == NULL) {
cout << "\t\t\t打开文件失败,";
system("pause");
return;
}
else {
while (q != NULL) {
fprintf(d, "%d\t%s\t%s\t%d\n", q->data.number, q->data.name, q->data.leibie, q->data.price);
q = q->next;
}
}
fclose(d);
cout << "\t\t\t保存成功,";
system("pause");
menu();
}
最后一部分为程序的运行部分,就不做解释了,都能看懂。
int menu() {
cout << "\n\t\t\t1.初始文件中菜品信息的添加";
cout << "\n\t\t\t2.从菜品文件往销售额文件添加信息";
cout << "\n\t\t\t3.退出\n";
int x;
cin >> x;
switch (x) {
case 1:
openfile();
add_message();
print_message();
save_file();
break;
case 2:
xiaoshou();
openfile();
diancai();
xiaoshufile(); //把销售出去的写入文件
break;
default:
return 0;
}
return 0;
}
int main() {
InitList(l); //这个链表是存储菜品信息
InitList(l2); //这个链表是存储销售信息
menu();
return 0;
}