用单链表写的图书管理程序,谁能帮我看看哪里错了

0 views
Skip to first unread message

不偷腥的猫

unread,
Jan 12, 2007, 8:22:27 AM1/12/07
to c语言基地
先是2个头文件:
LIST.H:
#include <iostream.h> // cin 及 cout
#include <malloc.h> // 用到申请内存函数 malloc()
和释放内存函数 free()
#include <string.h> // 字符串处理
#include <stdio.h> // 文件操作(读文件)
#include <stdlib.h> // system("cls")

struct book /*书目信息*/
{
char num[50];
char name[50];
char publish[100];
char date[8];
char author[20];
char isbn[20];
struct book * next;
};


typedef struct linknode //定义节点的类型
{
struct book bk;
bool flag;
struct linknode* next;
}nodetype;

class List
{
nodetype* head;

public:
List();
List::~List();

linknode* creatlist(int); //创建链表
int listlen(); //返回链表长度
nodetype* findnode(int);
//通过查找编号返回节点的指针
nodetype* find(char c[]);
//通过查找书名返回节点的指针
int find2(char c[]);
//通过查找书名返回节点的序号
nodetype* insnode(int); //插入节点
void delnode(int); //删除节点

nodetype* load();
//初始化:从外部读入数据

void readstr(FILE *f,char *string); //读行函数
bool check(char *a, char *b);
//对比两个字符串是否相等

void editbook(nodetype*); //编辑书目说明

void dispname(); //显示所有书目名称
void dispnode(nodetype* p);
void dispbook(nodetype*);
//显示一本书目的所有信息

};


Operater.h:
#include <iostream.h> // cin 及 cout
#include <string.h> // strcpy(): 字符串复制
#include <stdlib.h> // system("cls")
#include <stdio.h> // 文件操作(写文件)
#include "list.h" // 我们要创建类 List
的对象和节点指针,所以要把类的头文件包含进来

class Operater
{
List L1;
public:
void Loop(); //主循环
void display(); //显示菜单
};

下面是源程序:
LIST.CPP:

#include "list.h"

List::List()
{
head = NULL;
}

bool List::check(char *a, char *b)
//对比两个字符串是否相等
{
int i;
int j=strlen(b);
for(i=0; i<j; i++)
{
if(*a==*b)
{
a++;
b++;
}
else
return 0;
}
return 1;
}


nodetype* List::creatlist (int n) //创建链表
{
nodetype *h=NULL, *s, *t;
int i=1;

for(int j=0; j<n; j++)
{
if(i==1) //创建第一个节点
{
h=(nodetype*)malloc(sizeof(nodetype));
h->next=NULL;
t=h;
}
else //创建其余节点
{
s=(nodetype*)malloc(sizeof(nodetype));
s->next=NULL;
t->next=s;
t=s; //t
始终指向生成的单链表的最后一个节点
}

i++;
}

head=h;
return h;
}

/*
nodetype* List::creatlist (int n) //创建链表
{
nodetype *h=NULL;
int i=1;

for(int j=0; j<n; j++)
{
h=insnode(0);
}
head=h;
return h;
}
*/

void List::readstr(FILE *f,char *string)
{
do
{
//①: 先读入一行文本
fgets(string, 255, f); //fgets(): 从文件 f 读入长度为
255-1 的字符串
// 并存入到 string 中
} while ((string[0] == '/') || (string[0] == '\n'));

return;
}

nodetype* List::load()
{
FILE *fp;
nodetype *p;
char c[255];
int num;
if((fp=fopen("book.txt", "r"))==NULL)
{
cout<<"打开文件失败"<<endl;
return 0;
}
readstr(fp, c);
sscanf(c, "The Length Of Link: %d", &num);
//获取链表长度

p=creatlist(num); //创建链表

for(int i=0; i<num; i++)
{

readstr(fp, c);
strcpy(p->bk.num, c);
readstr(fp, c);
strcpy(p->bk.name, c);
readstr(fp, c);
strcpy(p->bk.publish, c);
readstr(fp, c);
strcpy(p->bk.date, c);
readstr(fp, c);
strcpy(p->bk.author, c);
readstr(fp, c);
strcpy(p->bk.isbn, c);

p=p->next;
}

fclose(fp);

return p;
}

void List::dispnode(nodetype* p)
//显示一个书目的所有信息
{
if(p!=NULL)
{
dispbook(p);

}
}

void List::dispname() //显示所有书目姓名
{
nodetype* p=head;
cout<<"现有的书目: "<<endl;
if(p==NULL)
cout<<"没有任何书目数据"<<endl;
while(p!=NULL)
{
cout<<"书目: "<<p->bk.name;

p=p->next;
}
}

int List::listlen() //返回链表长度
{
int i=0;
nodetype* p=head;
while(p!=NULL)
{
p=p->next;
i++;
}
return i;
}

nodetype* List::findnode (int i)
//通过查找序号返回节点的指针
{
nodetype* p=head;
int j=1;
if( i>listlen()||i<=0 ) // i 上溢或下溢
return NULL;
else
{
while( p!=NULL && j<i ) //查找第 i 个节点并由 p
指向该节点
{
j++;
p=p->next;
}
return p;
}
}

nodetype* List::find(char c[])
//通过查找书名返回节点的指针
{
nodetype* p=head;
int j=1;
strcat(c, "\n");
//从外部读入的字符串末尾都带了一个换行符
while( p!=NULL && !(check(c, p->bk.name))) //查找第 i
个节点并由 p 指向该节点
{
j++;
p=p->next;
}
return p;
}

int List::find2(char c[])
//通过查找书名返回节点的序号
{
nodetype* p=head;
int j=1;
strcat(c, "\n");
//从外部读入的字符串末尾都带了一个换行符
while( p!=NULL && !(check(c, p->bk.name))) //查找第 i
个节点并由 p 指向该节点
{
j++;
p=p->next;
}
return j;
}

nodetype* List::insnode(int i)
{
nodetype *h=head, *p, *s;
s=(nodetype*)malloc(sizeof(nodetype)); //创建节点 s
s->next=NULL;
if(i==0) //i=0 时 s 作为该单链表的第一个节点
{
s->next = h;
h=s; //重新定义头节点
}
else
{
p=findnode(i); //查找第 i 个节点,并由 p
指向该节点
if(p!=NULL)
{
s->next=p->next;
p->next=s;
}
else cout<<"输入的 i 值不正确"<<endl;
}
head=h;

return s;
}

void List::delnode(int i) //删除第 i 个节点
{
nodetype *h=head, *p=head, *s;
int j=1;
if(i==1) //删除第一个节点
{
h=h->next;
free(p);
}
else
{
p=findnode(i-1); //查找第 i-1 个节点,并由 p
指向这个节点
if(p!=NULL && p->next!=NULL)
{
s=p->next; // s 指向要删除的节点
p->next=s->next;
free(s);
}
else
cout<<"输入的 i 值不正确"<<endl;
}
head=h;
}

void List::editbook(nodetype* p)
{
char c[100];
cout<<"请输入书目编号: "<<endl;
cin>>c;
strcat(c, "\n");
strcpy(p->bk.num, c);

cout<<"请输入书目姓名:"<<endl;
cin>>c;
strcat(c, "\n");
strcpy(p->bk.name, c);

cout<<"请输入书目出版社:"<<endl;
cin>>c;
strcat(c, "\n");
strcpy(p->bk.publish, c);

cout<<"请输入出版日期(格式举例:1999-1-1): "<<endl;
cin>>c;
strcat(c, "\n");
strcpy(p->bk.date, c);

cout<<"请输入书目作者:"<<endl;
cin>>c;
strcat(c, "\n");
strcpy(p->bk.author, c);

cout<<"请输入书目ISBN:"<<endl;
cin>>c;
strcat(c, "\n");
strcpy(p->bk.isbn, c);

cout<<"编辑书目信息完成!"<<endl;

dispbook(p);
}

List::~List()
{
nodetype *pa=head, *pb;
if(pa!=NULL)
{
pb=pa->next;
if(pb==NULL)
free(pa);
else
{
while(pb!=NULL)
{
free(pa);
pa=pb;
pb=pb->next;
}
free(pa);
}
}
}
Main.cpp:


#include "operater.h"

void main()
{
Operater O1;
O1.Loop();
}
Operater.cpp:

#include "operater.h"

void Operater::display()
{
cout<<endl<<endl;
cout<<"**************************** 图书信息管理系统
**************************"<<endl;
cout<<"1: 添加一个书目信息"<<endl;
cout<<"2: 删除一个书目信息"<<endl;
cout<<"3: 显示所有书目的名称"<<endl;
cout<<"4:
根据书名显示单个书目所有信息"<<endl;
cout<<"5:
根据书名对单个书目进行编辑"<<endl;
cout<<"6: 保存数据"<<endl;
cout<<"0: 退出系统"<<endl;

cout<<"********************************************************************"<<endl;
}

void Operater::Loop()
{
List L1; //List 对象
char ch[20];
nodetype *p, *head;
int i; //存放节点序号

p=L1.load(); //初始化:从外部读入数据创建链表

head=p;
display();

while(1)
{
cout<<endl<<endl;
cin>>ch;

system("cls");
if(L1.check(ch, "1"))
{
p=L1.insnode(0);
head=p;

system("cls");
cout<<endl;
cout<<"************** 添加一个书目的信息
******************"<<endl;
cout<<"下面输入书目信息: "<<endl;
L1.editbook(p);

}

if(L1.check(ch, "2"))
{
system("cls");
cout<<endl;
cout<<"************** 删除一个书目信息
******************"<<endl;
L1.dispname();
cout<<"请输入书目名称: "<<endl;
cin>>ch;
i=L1.find2(ch);
L1.delnode(i);
}

if(L1.check(ch, "3"))
{
system("cls");
cout<<endl;
cout<<"************** 显示所有书目名称
******************"<<endl;
L1.dispname();
}

if(L1.check(ch, "4"))
{
system("cls");
cout<<endl;
cout<<"**************
根据书名显示单个书目所有信息 ******************"<<endl;
L1.dispname();
cout<<"请输入书目名称: "<<endl;
cin>>ch;
p=L1.find(ch);
L1.dispnode(p);
}

if(L1.check(ch, "6")) //保存数据
{
FILE *fp;
if((fp=fopen("student.txt", "w"))==NULL)
{
cout<<"打开文件失败"<<endl;
return;
}

int i;
char t[255];

//将 L1.listlen() 赋予字符串中的数字
sprintf(t, "The Length Of Link: %d\n", L1.listlen());

fputs(t, fp);
strcpy(t, "\n");
fputs(t, fp);

p=L1.findnode(1); //将链表头指针赋予
p

for(i=0; i<L1.listlen(); i++)
{
fputs(p->bk.num, fp); //输出地址
fputs(p->bk.name, fp); //输出生日

fputs(p->bk.publish, fp); //输出出版社
fputs(p->bk.date, fp); //输出出版日期
fputs(p->bk.author, fp); //输出书目作者
fputs(p->bk.isbn, fp); //输出书目ISBN

fputs(t, fp);

p=p->next;
}
p=head;
fclose(fp);
}

if(L1.check(ch, "5"))
{
char c[20];
system("cls");
cout<<endl;
cout<<"**************
根据书名对单个书目进行编辑 ******************"<<endl;
L1.dispname();
cout<<"请输入书目名称: "<<endl;
cin>>c;
p=L1.find(c);
L1.editbook(p);


}

else if(L1.check(ch, "0"))
return;
}
return;
}


总是产生LINK错误

麻烦高手给调试下,在线等,谢谢。
本人QQ:244713247

Reply all
Reply to author
Forward
0 new messages