#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <assert.h>#define LIST_DATA_FILENAME"list.data"//--------------------------------------------------------------------// Type definition//--------------------------------------------------------------------typedef struct list_node{ int value; char c; // you can define other variables here! struct list_node *prev; struct list_node *next;} list_node_t;typedef struct{ list_node_t *list_head; list_node_t *list_tail;} list_t;//--------------------------------------------------------------------// Function prototype//--------------------------------------------------------------------list_t *create_list(void);void release_list(list_t * list_p);list_node_t *list_create_node(int value, char c);void list_release_node(list_node_t * node_p);list_node_t *list_locate(list_t * list_p, int value, char c);int list_insert_before_node(list_t * list_p, list_node_t * node_p, int value, char ch);int list_insert_after_node(list_t * list_p, list_node_t * p, int value, char c);int list_insert_first(list_t * list_p, int value, char c);int list_insert_last(list_t * list_p, int value, char c);void list_delete_first_node(list_t * list_p);int list_delete_last_node(list_t * list_p);int list_delete_node(list_t * list_p, list_node_t * node_p);int list_delete(list_t * list_p, int value, char c);void list_print_node(list_node_t * p);void list_print_all(list_t * list_p);int list_get_length(list_t * list_p);void list_modify_node(list_t * list_p, int value, char c, int new_value, char new_c);int list_save_to_file(list_t * list_p, const char *filename);int list_load_from_file(list_t * list_p, const char *filename);//--------------------------------------------------------------------// Main function//--------------------------------------------------------------------int main(int argc, char **argv){ list_t *list1 = NULL; //------------------------------------------------------------------ // Create a empty list //------------------------------------------------------------------ list1 = create_list(); list_print_all(list1); //list_insert_after_node(list1, list1->list_head, 77, 'z'); list_insert_before_node(list1, list1->list_head, 77, 'z'); list_print_all(list1); list_insert_first(list1, 1, 'x'); list_print_all(list1); list_insert_after_node(list1, list1->list_head, 78, 'y'); list_insert_after_node(list1, list1->list_head, 100, 'a'); list_print_all(list1); list_node_t *p = list_locate(list1, 100, 'a'); list_print_node(p); //------------------------------------------------------------------ // Insert 2 nodes after node(100, 'a') //------------------------------------------------------------------ list_insert_after_node(list1, p, 101, 'b'); list_insert_after_node(list1, p, 102, 'c'); list_print_all(list1); fprintf(stdout, "\n---------- insert before node(%d, '%c') ----------\n", p->value, p->c); list_insert_before_node(list1, p, 99, 'w'); list_print_all(list1); list_delete_last_node(list1); list_delete_last_node(list1); list_delete_last_node(list1); list_delete_last_node(list1); list_delete_last_node(list1); list_print_all(list1); fprintf(stdout, "\n---------- delete node(%d, '%c') ----------\n", 1, 'x'); list_delete(list1, 1, 'x'); list_print_all(list1); fprintf(stdout, "\n---------- insert first ----------\n"); list_insert_first(list1, 2, 'm');// result: 2, 'm' -> 99, 'w' -> ... list_insert_first(list1, 3, 'n');// result: 3, 'n' -> 2, 'm' -> 99, 'w' -> ... list_insert_first(list1, 4, 'o');// result: 4, 'o' -> 3, 'n' -> 2, 'm' -> ... list_print_all(list1); fprintf(stdout, "\n---------- insert last ----------\n"); list_insert_last(list1, 5, 'u');// result: ... -> 101, 'b' -> 5, 'u' -> NULL list_insert_last(list1, 6, 'v');// result: ... -> 101, 'b' -> 5, 'u' -> 6, 'v' -> NULL list_insert_last(list1, 7, 's');// result: ... -> 101, 'b' -> 5' 'u' -> 6, 'v' -> 7, 's' -> NULL list_print_all(list1); fprintf(stdout, "\n---------- save & load list ----------\n"); list_save_to_file(list1, LIST_DATA_FILENAME); list_t *list2 = create_list(); list_load_from_file(list2, LIST_DATA_FILENAME); list_print_all(list2); fprintf(stdout, "\n---------- release list2 ----------\n"); release_list(list2); fprintf(stdout, "\n---------- release list1 ----------\n"); release_list(list1); fprintf(stdout, "\n---------- finished ----------\n"); return 0;}list_node_t *list_create_node(int value, char c){ list_node_t *p = malloc(sizeof(list_node_t)); if (!p) { fprintf(stderr, "Allist_locate memory for new node failed.\n"); return NULL; } p->value = value; p->c = c; p->prev = NULL; p->next = NULL; return p;}void list_release_node(list_node_t * node_p){ if (node_p) { // free dynamic allocated resources. free(node_p); }}void list_print_node(list_node_t * node_p){ fprintf(stdout, "p: %8p, value = %8d, char = '%4c', next = %8p, prev = %8p\n", node_p, node_p->value, node_p->c, node_p->next, node_p->prev);}void list_print_all(list_t * list_p){ fprintf(stdout, "\n\n##### Calling %s:%d:%s() ...\n", __FILE__, __LINE__, __func__); fprintf(stdout, "list: %p, list->list_head: %p, list->list_tail: %p\n", list_p, list_p->list_head, list_p->list_tail); list_node_t *p; p = list_p->list_head; while (p) { //fprintf(stdout, "p: %p, value = %d, char = %c, next = %p\n", p, p->value, p->c, p->next); list_print_node(p); p = p->next; } fprintf(stdout, "##### Leaving from %s:%d:%s() ...\n\n", __FILE__, __LINE__, __func__);}void list_print_all_another(list_t * list_p){ fprintf(stdout, "\n\n##### Calling %s:%d:%s() ...\n", __FILE__, __LINE__, __func__); fprintf(stdout, "list: %p, list->list_head: %p, list->list_tail: %p\n", list_p, list_p->list_head, list_p->list_tail); if (!list_p->list_head) { assert(!list_p->list_tail); return; } list_node_t *p = list_p->list_head; while (p != list_p->list_tail) { //fprintf(stdout, "p: %p, value = %d, char = %c, next = %p\n", p, p->value, p->c, p->next); list_print_node(p); p = p->next; } list_print_node(list_p->list_tail); fprintf(stdout, "##### Leaving from %s:%d:%s() ...\n\n", __FILE__, __LINE__, __func__);}list_node_t *list_locate(list_t * list_p, int value, char c){ list_node_t *p = list_p->list_head; while (p) { if (p->value == value && p->c == c) { // found it! fprintf(stdout, "%s:%d:%s(%d, '%c'): found!\n", __FILE__, __LINE__, __func__, value, c); break; } p = p->next; } if (p == NULL) { fprintf(stdout, "%s:%d:%s(%d, '%c'): not found!\n", __FILE__, __LINE__, __func__, value, c); } return p;}int list_insert_first(list_t * list_p, int value, char c){ list_insert_before_node(list_p, list_p->list_head, value, c); return 0;}int list_insert_last(list_t * list_p, int value, char c){ list_insert_after_node(list_p, list_p->list_tail, value, c); return 0;}int list_insert_before_node(list_t * list_p, list_node_t * node_p, int value, char ch){ list_node_t *new_node = list_create_node(value, ch); if (!new_node) { fprintf(stderr, "Create new node failed.\n"); return -1; } if (list_p->list_head == NULL) { list_p->list_head = new_node; list_p->list_tail = new_node; return 0; } new_node->next = node_p; new_node->prev = node_p->prev; if (node_p->prev) { node_p->prev->next = new_node; } else { fprintf(stdout, "Insert node before head.\n"); list_p->list_head = new_node; } node_p->prev = new_node; return 0;}int list_insert_after_node(list_t * list_p, list_node_t * node_p, int value, char c){ // create new_node list_node_t *new_node = list_create_node(value, c); if (!new_node) { fprintf(stderr, "Create new list_node object failed.\n"); return -1; } if (list_p->list_head == NULL) { list_p->list_head = new_node; list_p->list_tail = new_node; return 0; } new_node->next = node_p->next; new_node->prev = node_p; if (node_p->next) { node_p->next->prev = new_node; } else { fprintf(stdout, "Insert node after tail.\n"); list_p->list_tail = new_node; } node_p->next = new_node; return 0;}int list_get_length(list_t * list_p){ int length = 0; list_node_t *p = list_p->list_head; while (p) { length++; p = p->next; } return length;}void list_modify_node(list_t * list_p, int value, char c, int new_value, char new_c){ //list_node_t *list_locate(list_t * list_p, int value, char c); list_node_t *node_p = list_locate(list_p, value, c); if (node_p) { node_p->value = new_value; node_p->c = new_c; fprintf(stdout, "Modify node %p successfully.\n", node_p); } else { fprintf(stderr, "Cannot locate node(%d, '%c'), failed.\n", value, c); }}void list_delete_first_node(list_t * list_p){ list_delete_node(list_p, list_p->list_head);}int list_delete_last_node(list_t * list_p){ list_delete_node(list_p, list_p->list_tail); return 0;}int list_delete(list_t * list_p, int value, char c){ list_node_t *node_p = list_locate(list_p, value, c); if (!node_p) { fprintf(stderr, "%s:%d:%s(): Cannot locate target node(%d, '%c'), give up.\n", __FILE__, __LINE__, __func__, value, c); return -1; } list_delete_node(list_p, node_p); return 0;}int list_delete_node(list_t * list_p, list_node_t * node_p){ if (node_p->prev) { node_p->prev->next = node_p->next; } else { // first node list_p->list_head = node_p->next; } if (node_p->next) { node_p->next->prev = node_p->prev; } else { // last node list_p->list_tail = node_p->prev; } free(node_p); return 0;}//--------------------------------------------------------------------// save_to_file & load_from_list//--------------------------------------------------------------------int list_save_to_file(list_t * list_p, const char *filename){ fprintf(stdout, "\n\n##### Calling %s:%d:%s() ...\n", __FILE__, __LINE__, __func__); FILE *fp = fopen(filename, "wb"); if (fp == NULL) { fprintf(stderr, "Open data file %s failed: %s\n", filename, strerror(errno)); return -1; } list_node_t *p = list_p->list_head; while (p) { //size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE * stream); fwrite(p, sizeof(list_node_t), 1, fp); p = p->next; } fflush(fp); fclose(fp); fprintf(stdout, "##### Leaving from %s:%d:%s() ...\n\n", __FILE__, __LINE__, __func__); return 0;}int list_load_from_file(list_t * list_p, const char *filename){ fprintf(stdout, "\n\n##### Calling %s:%d:%s() ...\n", __FILE__, __LINE__, __func__); FILE *fp = fopen(filename, "rb"); if (fp == NULL) { fprintf(stderr, "Open list data file %s failed: %s\n", filename, strerror(errno)); return -1; } while (1) { list_node_t new_node; size_t n; //size_t fread(void *ptr, size_t size, size_t nmemb, FILE * stream); n = fread(&new_node, sizeof(list_node_t), 1, fp); if (n < 1) { if (feof(fp)) {// reach end-of-filebreak; } else {// error occurbreak; } } else { list_insert_last(list_p, new_node.value, new_node.c); } } fclose(fp); fprintf(stdout, "##### Leaving from %s:%d:%s() ...\n\n", __FILE__, __LINE__, __func__); return 0;}//--------------------------------------------------------------------// list management functions//--------------------------------------------------------------------list_t *create_list(void){ list_t *p = malloc(sizeof(list_t)); if (!p) { fprintf(stderr, "Create new list failed.\n"); return NULL; } p->list_head = NULL; p->list_tail = NULL; return p;}void release_list(list_t * list_p){ list_node_t *p = list_p->list_head; while (p) { list_node_t *current = p; p = p->next; fprintf(stdout, "Release node: "); list_print_node(current); free(current); } free(list_p);}// vim: tabstop=8