这个程序主要用到的是C的链表知识。算属于数据结构中的吧,简单的单向链表。我很惭愧阿,还没搞懂二叉树。要是有牛人指点二三,不胜感激阿。废话少说,代码供上,牛人莫笑。
//这是个简单的书本录入程序,实现的是从输入书本名,作者和价钱,保存到一结构体组成的内存空间里。退出时信息会丢失。 //
//功能很简单,但用到了C中很多知识点,主要是学习结构体的使用和链表使用和函数的用法。我花了点时间用中文注释了下,供//
//个人参考 //,程序编译成功运行,有爱好者可下载在UNIX平台编译运行。因水平实在有限,难免错误地方太多,望见谅。大家//
//可以互相学习探讨,我的联系方世如下
//MSN:[email]wu23qing45ying@163.com[/email] //
//QQ: 46499596 //
//E-mail: [email]carywu@yahoo.cn[/email] / [email]wu23qing45ying@163.com[/email] //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////
//头文件 //
//////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define NAME_SIZE 50
#define MAXBOOKS 30
//////////////////////////////////////////////////
//结构体定义 //
//////////////////////////////////////////////////
typedef struct library
{
char name[NAME_SIZE]; //书名,用的是数组,
char auther[NAME_SIZE]; //作者名。
float value; //价格
int number; //序号
struct library *next; //链表指针。
} library_t, *point;
//////////////////////////////////////////////////
//结构体定义 //
//////////////////////////////////////////////////
void delete_enter (char *s);
void print_list (point current);
void book_append (point head);
void book_delete (point current);
int number = 0; //全局定义序号,初始值为0.
//////////////////////////////////////////////////
//主函数 //
//////////////////////////////////////////////////
int
main (int argc, char **argv)
{
point current = NULL, head = NULL, prev = NULL; //定义当前连表指针,头指针,前一个指针。
fprintf (stdout, "Please input the book name:\n");
char temp_storage[NAME_SIZE]; //定义一临时存储书名的数组。因为指针还为分配内存,不能用。
while (fgets (temp_storage, NAME_SIZE, stdin) != NULL //我用的是fgets,会将回车符存入,所以需要个删除回车做法。
&& temp_storage[0] != '\n')
{
delete_enter (temp_storage); //删除回车符的函数,在下面有具体。
current = (point) malloc (sizeof (library_t)); //分配当前节点的内存,用于存储数据。
strcpy (current->name, temp_storage); //将临时中的字符串复制到结构题中的name数组中。
fprintf (stdout, "please input the auther name\n");
fgets (current->auther, NAME_SIZE, stdin); //同上,输入作者名。有个问题是没做错误检测。
delete_enter (current->auther); //同上。
fprintf (stdout, "please input the book value\n");
scanf ("%f", ¤t->value); //输入价格。直接用scanf。
number++; //序号自加。
current->number += number; //传给结构题中的number,实现每多一链表节点序号增加1。
if (head == NULL) //当头指针为空时,指向当前节点。
{
head = current;
}
else //否则,前指针的下一跳指向当前节点。 这样三个指针都指向了具体的节点。
{
prev->next = current;
}
current->next = NULL; //当前指针的下一跳设为空。
fprintf (stdout, "number name auther value\n"); //输出信息。每次输完一个节点信息后,就输出查看。
fprintf (stdout, "%d %10s %10s %.2f\n", current->number,
current->name, current->auther, current->value);
prev = current; //将前指针指向当前节点。
fprintf (stdout, "Please input the next name:\n");
while (getchar () != '\n')
continue;
}
fprintf (stdout, "below is the append program\n");
current = head; //将当前指针指回到头节点,实现链表的遍历。
book_append (current); //这是个按照序号选择来插入新节点信息的函数。
fprintf (stdout, "show the total book list\n");
current = head; //同上。当前指针回归到头节点。
print_list (current); //这是个打印整个链表信息的函数。
fprintf(stdout, "below is the delete program\n");
current = head; //同上。
book_delete(current); //这是个按照序号选择来删除节点的函数。
fprintf (stdout, "show the total book list\n");
current = head;
print_list (current); //删除后再打印一次。我很苦恼似乎重复使用打印函数。
return 0;
}
void
delete_enter (char *s) //删除回车空行函数,很简单。
{
int i;
while (s[i] != '\n')
++i;
if (s[i] == '\n')
s[i] = '\0';
}
void
print_list (point current)
{
fprintf (stdout,
"number %10s book_name %10s book_auther %10s book_value %10s\n",
" ", " ", " ", " ");
while (current != NULL) //在当前指针指向空节点时结束。
{
fprintf (stdout, "%d %s %10s %10s %.2f\n",
current->number, current->name, current->auther, " ",
current->value);
fprintf (stdout, "%20s\n", "--------------");
current = current->next;
}
}
void
book_append (point current)
{
int word_number;
point new_code = NULL;
fprintf (stdout, "please input the number you want to add behind\n");
scanf ("%d", &word_number);
for (; current != NULL; current = current->next)
{
if (word_number == current->number)
{
new_code = (point) malloc (sizeof (library_t));
fprintf (stdout, "please input the book name\n");
while (getchar () != '\n')
continue;
fgets (new_code->name, NAME_SIZE, stdin);
delete_enter (new_code->name);
fprintf (stdout, "please input the book auther\n");
fgets (new_code->auther, NAME_SIZE, stdin);
delete_enter (new_code->auther);
fprintf (stdout, "please input the book value\n");
scanf ("%f", &new_code->value);
number++;
new_code->number += number;
new_code->next = current->next;
current->next = new_code;
break;
}
else
continue;
}
}
void
book_delete (point current) //当前节点被指向了头节点。
{
int word_number;
point prev; //定义一个新的辅助前指针。
fprintf (stdout, "please input the number you want to delete\n");
scanf ("%d", &word_number); //选择要删除的序号。
while (current != NULL)
{
prev = current; //删除单向链表其实很简单,前指针指向当前节点。
current = current->next; //当前指针指向下一个节点。
if (word_number == current->number) //在序号相等情况下。
{
prev->next = current->next; //将前节点的下一跳指向当前节点的下一跳节点,也就是把当前节点孤立不链接。
free (current); //free掉当前节点。
break; //退出。
}
else
continue; //多此一举,不过写上好看些。
}
}