2、在第 2.11 节 “本节综合练习”的习题1中规定了一种日志文件的格式,每行是一条记录,由行号、日期、时间三个字段组成,由于记录是按时间先后顺序写入的,可以看作所有记录是按日期排序的,对于日期相同的记录再按时间排序。现在要求从这样的一个日志文件中读出所有记录组成一个链表,在链表中首先按时间排序,对于时间相同的记录再按日期排序,最后写回文件中。比如原文件的内容是:
1 2009-7-30 15:16:42 2 2009-7-30 15:16:43 3 2009-7-31 15:16:41 4 2009-7-31 15:16:42 5 2009-7-31 15:16:43 6 2009-7-31 15:16:44
重新排序输出的文件内容是:
1 2009-7-31 15:16:41 2 2009-7-30 15:16:42 3 2009-7-31 15:16:42 4 2009-7-30 15:16:43 5 2009-7-31 15:16:43 6 2009-7-31 15:16:44
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <time.h> 4 #include "dlink_log.h" 5 #include <string.h> 6 7 int get_i(FILE *fp, char *name); 8 int main(int argc, char *arg[]) 9 { 10 if(argc>2){ 11 printf("the arg[1] is %s\n", arg[1]); 12 FILE *fp = fopen(arg[1], "r"); 13 if(fp == NULL) { 14 perror("Open file abcde"); 15 }else{ 16 get_i(fp, arg[2]); 17 } 18 fclose(fp); 19 } 20 21 22 23 } 24 25 int get_i(FILE *fp, char *name) 26 { 27 char *a = malloc(sizeof(char)); 28 int num=0; 29 link node; 30 while(fgets(a, 100, fp) != NULL){ 31 char *y=malloc(sizeof(char)), *d =malloc(sizeof(char)); 32 printf("line----------------%s\n", a); 33 sscanf(a, "%d %s %s", &num, y, d); 34 printf("==========sum=%d y=%s d=%s\n", num, y, d); 35 node = make_node(num, y, d); 36 printf("==========node->day=%s\n", node->day); 37 insert_sort(node); 38 } 39 list_node(); 40 FILE *fp1 = fopen(name, "w+"); 41 re_write(fp1); 42 fclose(fp1); 43 return num; 44 } 45 46
1 /* dlink_log.h */ 2 3 #include <stdio.h> 4 #include <stdlib.h> 5 #ifndef DOUBLYLINKEDLIST_H 6 #define DOUBLYLINKEDLIST_H 7 8 typedef struct node *link; 9 struct node { 10 int num; 11 char *date; 12 char *day; 13 link pre, next; 14 }; 15 16 link make_node(int num, char *date, char *day); 17 void free_node(link p); 18 void insert(link p); 19 void delete(link p); 20 void traverse(void (*visit)(link)); 21 void destroy(void); 22 void enqueue(link p); 23 link dequeue(void); 24 void insert_sort(link p); 25 void list_node(void); 26 int lg(link a, link b); 27 void re_write(FILE *fp); 28 29 #endif
/* dlink_log.c */ 2 #include <stdlib.h> 3 #include <stdio.h> 4 #include "dlink_log.h" 5 #include "string.h" 6 7 struct node tailsentinel; 8 struct node headsentinel = {0, NULL, NULL, NULL, &tailsentinel}; 9 struct node tailsentinel = {0, NULL, NULL, NULL, &headsentinel}; 10 static link head = &headsentinel; 11 static link tail = &tailsentinel; 12 13 link make_node(int num, char *date, char *day) 14 { 15 link p = malloc(sizeof *p); 16 p->num = num; 17 p->date = date; 18 p->day = day; 19 p->pre = p->next = NULL; 20 return p; 21 } 22 23 void free_node(link p) 24 { 25 free(p); 26 } 27 28 int lg(link node, link p) 29 { 30 int r; 31 printf("num=%d, node->day=%s, num=%d,p->day=%s\n", 32 node->num, node->day, p->num, p->day); 33 r = strcmp(node->day, p->day); 34 //r = node->num > p->num; 35 printf("r=%d\n", r); 36 r = r>=0; 37 printf("r=%d\n", r); 38 return r; 39 } 40 41 42 void insert_sort(link p) 43 { 44 printf("insert_sort p->day=%s\n", p->day); 45 link node = head; 46 for(;node->next != tail && lg(node->next, p); node=node->next); 47 //for(;node->next != tail && node->next->num < p->num; node=node->next); 48 p->next = node->next; 49 p->pre = node; 50 node->next->pre=p; 51 node->next = p; 52 } 53 54 55 void insert(link p) 56 { 57 p->next = head->next; 58 head->next->pre = p; 59 head->next = p; 60 p->pre = head; 61 } 62 63 void delete(link p) 64 { 65 p->pre->next = p->next; 66 p->next->pre = p->pre; 67 } 68 69 void traverse(void (*visit)(link)) 70 { 71 link p; 72 for(p=head->next; p!=tail; p=p->next){ 73 visit(p); 74 } 75 } 76 77 78 void destroy(void) 79 { 80 link q, p = head->next; 81 head->next = tail; 82 tail->pre = head; 83 while(p!=tail){ 84 q = p; 85 p=p->next; 86 free_node(q); 87 } 88 } 89 90 void enqueue(link p) 91 { 92 insert(p); 93 } 94 95 link dequeue(void) 96 { 97 if(tail->pre ==head){ 98 return NULL; 99 }else{ 100 link p = tail->pre; 101 delete(p); 102 return p; 103 } 104 } 105 106 107 void list_node(void) 108 { 109 printf("--pre-----------------\n"); 110 link node = tail->pre; 111 for(; node != head; node=node->pre){ 112 printf("num=%d, node->day=%s\n", node->num, node->day); 113 } 114 printf("-next------------------\n"); 115 for(node=head->next; node!=tail; node=node->next){ 116 printf("num=%d,date=%s, node->day=%s\n", node->num, node->date, node->day); 117 } 118 } 119 120 void re_write(FILE *fp) 121 { 122 link node = tail->pre; 123 char *str = malloc(sizeof(char));//malloc(NULL); 124 for(; node != head; node=node->pre){ 125 printf("re_write num=%d, date=%s, day=%s\n", node->num, node->date, node->day); 126 127 sprintf(str, "%d %s %s\n", node->num, node->date, node->day); 128 fputs(str, fp); 129 } 130 }
相关推荐
如果`dul_list`是一个源代码文件,它可能包含了上述的双向链表操作的实现。 总结,本项目涉及的主要是使用C语言在VC++命令行环境下实现双向链表,包括其基本操作和可能的扩展功能。通过阅读和分析`...
链表可以分为单向链表和双向链表,其中单向链表中的每个节点只包含一个指向后继节点的指针,而双向链表中的每个节点除了指向后继节点的指针外,还有一个指向前驱节点的指针。 ### 二、C语言中链表的基本操作 #### ...
在C++编程中,链表是一种非常重要的数据结构,它在处理动态数据集合时具有...熟练掌握链表和文件操作,可以解决很多实际问题,例如数据存储、日志记录等。同时,这也为其他复杂数据结构和算法的学习打下了坚实的基础。
`std::list`是一个双向链表容器,提供了许多便捷的操作接口,如`push_back`、`push_front`、`erase`等,可以大大简化链表的编程工作。 总之,C++用链表实现管理系统充分利用了链表的灵活性和动态性,能够有效地管理...
10. **BILIST.PLG**:可能是一个插件或日志文件,与项目开发过程相关。 通过这些文件,我们可以了解到C++中的面向对象编程概念,如类的定义(BILIST.H)、实现(BILIST.CPP)以及如何进行单元测试(LISTTEST.CPP)...
这可能涉及到对日志文件的数据结构设计,例如使用双向链表,或者在读取时动态排序。 4. **C#编程实践**:"LogHelper.cs" 是一个C#源代码文件,说明这个日志助手是用C#语言实现的。在C#中,我们可以使用`...
描述中提到的“其他相关文件”可能包括测试脚本、配置文件、编译日志等,这些辅助文件有助于开发和调试链表实现。 在学习和实践这个项目时,你将深入理解数据结构的基本原理,特别是双链表的运作机制。这对于理解和...
同时,文档可能还会涉及错误处理和性能优化技巧,比如在插入或删除节点时避免无效遍历,或者在处理大量数据时考虑使用双向链表以提高效率。 总之,掌握单链表的基本操作对于任何程序员来说都是至关重要的,因为它...
在计算机科学中,理解和掌握单链表的操作至关重要,因为它是许多复杂数据结构如双向链表、哈希表等的基础。 **单链表的定义** 单链表由头节点开始,头节点可能存储数据,也可能只是一个指向第一个实际数据节点的...
2. **双向循环链表**:双向链表允许从两个方向遍历,而循环链表则没有头尾之分,最后一个节点指向第一个节点。`m_slink.c`可能包含了双向循环链表的创建、遍历、插入和删除等操作,适合于需要前后移动元素的场景。 ...
`LinkedList`则是双向链表,适合频繁插入和删除。通过例子,你可以掌握如何创建、添加、删除、遍历列表元素以及转换列表等操作。 时间操作在Java中通常涉及到`java.time`包,这是Java 8引入的新特性。你可以学习...
缓冲区管理使用了双向链表结构,例如REPL(正在使用的缓冲区)、REPL-AUX(准备用于I/O或CR构建的缓冲区)、WRITE(需要I/O的脏缓冲区)和CKPT-Q(写入检查点的脏缓冲区)。通过Touch Count来确定REPL链中缓冲区的...
双向链表允许快速地在链表的前后添加、删除和修改元素,这使得在用户进行增删改查操作时,系统能高效地响应。链表节点通常包含数据(如bug ID、描述、状态、创建时间等)以及指向前后节点的指针,这样就可以方便地...
- 链表:实现双向链表,方便进行动态数据结构的管理。 - 哈希表:用于快速查找和存储键值对,提高数据访问效率。 - 锁:提供线程互斥锁,确保多线程环境下的数据一致性。 2. 网络通信: - socket编程:封装了...
链表分为单链表、双向链表等类型,通过指针连接节点,可以灵活地插入和删除元素,适用于动态数据集合。 文件是程序与外部世界交互的重要方式,可以用于持久化数据、读写配置文件、日志记录等。C 语言提供了文件操作...
例如,可以使用双向链表配合哈希表,链表用于快速遍历和状态更新,哈希表用于快速定位影碟信息。 接着,"数据结构"的选择直接影响到系统的性能和复杂性。例如,如果我们选择使用数据库管理系统,如MySQL或SQLite,...
在C++中,`list`是一种双向链表,它提供了高效的插入和删除操作,尤其是当这些操作发生在链表的中间或开头时。与其他STL容器如`vector`不同,`list`不保证元素的连续存储,因此它不适合作为需要随机访问的场景,但在...
- **高阶**: 数据结构和算法(如单双向链表、二叉树、栈、队列等)、工程管理和调试。 #### 三、嵌入式Linux应用开发 嵌入式Linux应用开发涉及系统I/O、多进程/多线程编程、网络编程以及数据库编程等内容。这部分是...
另外一个是 next、prev 指示的一个双向链表,而这个双向链表分为两个一个 in_use_,一个 lru_,主要为了区别不同节点的引用个数,in_use_ 是表示正在被使用的节点,而 lru_ 是表示当前没被使用,有可能会被使用而...
首先,文档中提到了双向链表的操作函数,例如`list_add`用于在链表的尾部添加一个新元素,而`list_add_tail`则在链表的头部添加。这些操作对于管理动态数据集合是非常重要的,例如在设备驱动中管理设备请求队列。`...