book结构体定义如下:
struct book //定义book结构体
{
int number; //编号
char name[30]; //书名
char category[10]; //类别
char lentuser[12]; //借书人的usernum
int lent; //是否借出(已借为1,未借为0)
int year; //借出时间——年
int month; //借出时间——月
int day; //借出时间——日
struct book *next; //一个指向book类型对象的指针
};
library.txt截图如下:
有疑问的make_linklist()函数的代码如下:
//从library.txt中读取数据至链表
struct book *make_linklist() //这货是条指针函数,本质就是段函数(在汇编程序里面函数就是code segment哈哈和 data segment并列的存在)
//所以函数和数组都是差不多的东西,声明函数或数组之后默认会分配给他们一个指向他们首地址的指针
//而且这个指针的名字跟函数名/数组名一样
//make_linklist()的返回值是(struct book *) //(struct book *)就是指向类型为book的结构体的指针
{
struct book *head; //指针head现在可以指向任何类型为book的结构体
head = (struct book *)malloc(sizeof(struct book)); //分配book结构体大小的内存,
//并将这块内存按照book结构体的大小划分单元,
//然后将这块内存的首地址赋值给指针变量head,即head为头指针
head->next = NULL; //将头节点的指针域赋值为null,即初始化一个带头结点的单链表
FILE *fp; //定义fp,一个指向文件类型的文件指针(FILE *)
fp = fopen("library.txt", "r+"); //告诉fp要指向的文件是library.txt (r+表示允许读写文件)
//如果library.txt文件不存在
if (fp == NULL)
fp = fopen("library.txt", "w+"); // w+ ,如果文件已经存在,将建立一个新文件覆盖原文件(很缺德啊……),并且支持读取。
//此处用于创建library.txt文件
//如果检测到library.txt为空
if (check_void_file() == 0)
{
printf("图书数据库为空!");
return head; //返回创建链表的头指针,即返回整个链表,这样就可以被其他地方所用了
}
//library.txt不为空
struct book *p;
p = head; //给p赋值为头指针,即让p指向头节点
char ch;
while(!feof(fp)) //当文件指针fp没有到达末尾,循环执行从library.txt读取数据到链表
//(feof()用于检测文件是否结束,如果没有结束,返回值是0,结束了是1)
{
struct book *new_book_init; //指针new_book_init现在可以指向类型为book的任何结构体
new_book_init = (struct book *)malloc(sizeof(struct book)); //分配book结构体大小的内存,并将这块内存按照book结构体的大小划分单元,
//然后将这块内存的首地址赋值给指针变量new_book_init,
//即new_book_init为头指针
/*依序从fp指向的文件流中赋值给new_book_init指针指向的结构体的成员,开始*/
//第一行
fscanf(fp, "%d", &new_book_init->number);
ch = fgetc(fp);
fscanf(fp, "%[^\n]%*c", new_book_init->name);
//第二行
fscanf(fp, "%[^\n]%*c", new_book_init->category);
//第三行
fscanf(fp, "%[^\n]%*c", new_book_init->buser);
//第四行
fscanf(fp, "%d", &new_book_init->lent);
ch = fgetc(fp); //吃空格,让fp下移
fscanf(fp, "%d", &new_book_init->year);
ch = fgetc(fp); //吃空格,让fp下移
fscanf(fp, "%d", &new_book_init->month);
ch = fgetc(fp); //吃空格,让fp下移
fscanf(fp, "%d", &new_book_init->day);
ch = fgetc(fp); //吃换行,让fp下移
//不要忘了给结构体内的成员next指针赋值为null,不要让next成为野指针
new_book_init->next = NULL;
/*依序从fp指向的文件流中赋值给new_book_init指针指向的结构体的成员,结束*/
p->next = new_book_init;
p = p->next;
}
fclose(fp);
return head;
}
为啥需要定义指针p呢?直接将head = new_book_init
不可以吗?
你创造的是單向連結串列。
如果没有p,用
head = new_book_init
。那经过while循环之后,head实际指向連結串列的尾部,然后return head。这样做的问题是之后你不能遍历串列,因为尾部没有指针指向前面的node。