//link_list.h
#ifndef LINK_LIST_H
#define LINK_LIST_H
#define NAME_SIZE 20
#define ADDR_SIZE 40
#define NUM_SIZE 16
typedef enum
{
      FALSE,
      TRUE
}BOOL;
struct info
{
      char name[NAME_SIZE];
      char tel_num[NUM_SIZE];
      char address[ADDR_SIZE];
};
typedef struct info Item;
typedef struct node
{
      Item item;
      struct node *next;
}Node;
typedef Node *PtrList;
void init(PtrList *ptr);
BOOL list_is_empty(const PtrList *ptr);
BOOL list_is_full(const PtrList *ptr);
unsigned int count_list_items(const PtrList *ptr);
BOOL add_list_item(Item item, PtrList *ptr);
void display_all_items(const PtrList *ptr, void (* pfunc)(Item item));
void reset_list(PtrList *ptr);
#endif
//link_list.c
#include <stdio.h>
#include <stdlib.h>
#include "link_list.h"
static void copy_to_node(Item item, Node *pnode);
void init(PtrList *ptr)
{
      *ptr = NULL;
}
BOOL list_is_empty(const PtrList *ptr)
{
      if (NULL == *ptr)
            return TRUE;
      else
            return FALSE;
}
BOOL list_is_full(const PtrList *ptr)
{
      Node *pt;
      BOOL b_full;

      pt = (Node *)malloc(sizeof(Node));
      if (NULL == pt)
            b_full = TRUE;
      else
            b_full = FALSE;
      free(pt);
      return b_full;
}
unsigned int count_list_items(const PtrList *ptr)
{
      unsigned int count = 0;
      Node *pnode = *ptr;
      while(pnode)
      {
            ++count;
            pnode = pnode->next;
      }
      return count;
}
BOOL add_list_item(Item item, PtrList *ptr)
{
      Node *pnew;
      Node *scan = *ptr;

      pnew = (Node *)malloc(sizeof(Node));
      if (NULL == pnew)
            return FALSE;

      copy_to_node(item, pnew);
      pnew->next = NULL;
      if (NULL == scan)
            *ptr = pnew;
      else
      {
            while (scan->next)
            scan = scan->next;
            scan->next = pnew;
      }
      return TRUE;
}
void display_all_items(const PtrList *ptr, void (* pfunc)(Item item))
{
      Node *pnode = *ptr;
      while (pnode != NULL)
      {
            (*pfunc)(pnode->item);
            pnode = pnode->next;
      }
}
void reset_list(PtrList *ptr)
{
      Node *ptemp;
      while (*ptr != NULL)
      {
            ptemp = (*ptr)->next;
            free(*ptr);
            *ptr = ptemp;
      }
}
static void copy_to_node(Item item, Node *pnode)
{
      pnode->item = item;
}
//test_link_list.c
#include <stdio.h>
#include <stdlib.h>
#include "link_list.h"
void display_info(Item item);
int main(void)
{
      PtrList ptr_infolist;
      Item current_item;
      init(&ptr_infolist);
      if (list_is_full(&ptr_infolist))
      {
            fprintf(stderr, "Memory is not available!\n");
            exit(1);
      }
      puts("Enter the name: ");
      while (gets(current_item.name) != NULL && current_item.name[0] != '\0')
      {
            puts("Enter the tel_num: ");
            gets(current_item.tel_num);
            printf("%s\n", current_item.tel_num);
            puts("Enter the address: ");
            gets(current_item.address);
            if (FALSE == add_list_item(current_item, &ptr_infolist))
            {
                  fprintf(stderr, "Memor is not available!\n");
                  break;
            }
            if (list_is_full(&ptr_infolist))
            {
                  printf("The list has full!\n");
                  break;
            }
            puts("Enter next name (empty line to stop)");
      }
      if (list_is_empty(&ptr_infolist))
            printf("No data entered.\n");
      else
      {
            printf("Here is the info list:\n");
            display_all_items(&ptr_infolist, display_info);
      }
      printf("You have entered %d item.\n", count_list_items(&ptr_infolist));
      reset_list(&ptr_infolist);
      printf("----end----\n");
      system("pause");
      return 0;
}
void display_info(Item item)
{
      printf("name: %-10s tel_num: %-16s address: %-20s", item.name, item.tel_num, item.address);
}