#include "./includes/lrc.h" FILE *open_lrc_file(const char *lrc_path) { FILE *fp = fopen(lrc_path, "rb"); // 以二进制只读方式打开歌词文件 if (fp == NULL) // 如果打开歌词文件失败 { printf("歌词打开失败\n"); perror("fopen"); return NULL; // 打开歌词文件失败,退出程序 } return fp; } long get_lrc_size(FILE *fp) { fseek(fp, 0, SEEK_END); // fseek()将文件指针移动到文件末尾 long size = ftell(fp); // ftell()返回当前文件指针位置, 即文件大小 rewind(fp); // rewind()将文件指针移动到文件开头 return size; } char *get_lrc_mem_data(FILE *fp) { long lrc_size = get_lrc_size(fp); // 获取歌词文件大小 char *lrc_mem_data = (char *)calloc(1, lrc_size + 1); // 为歌词数据分配内存,+1 是为了保存最后位置结束符 if (NULL == lrc_mem_data) { printf("歌词数据分配内存失败\n"); perror("malloc"); fclose(fp); // 关闭歌词文件 return NULL; // 为歌词数据分配内存失败,退出程序 } fread(lrc_mem_data, lrc_size, 1, fp); // 读入歌词数据 fclose(fp); // 关闭歌词文件 return lrc_mem_data; // 返回歌词数据 } LRC *insert_lrc_node(LRC *head, LRC new_node) { LRC *p = head; // 定义临时指针变量 if (p == NULL) // 如果链表为空 { head = (LRC *)malloc(sizeof(LRC)); // 为链表分配内存 if (head == NULL) // 如果分配内存失败 { printf("歌词节点分配内存失败\n"); // 打印错误信息 perror("malloc"); // 打印错误信息 return NULL; // 返回 NULL } head->time = new_node.time; // 将新节点的时间点赋值给链表头节点 strcpy(head->lrc_buf, new_node.lrc_buf); // 将新节点的歌词内容赋值给链表头节点 head->next = NULL; // 将链表头节点的 next 指针域置为 NULL return head; // 返回链表头节点 } while (p->next != NULL) // 遍历链表,找到链表尾节点 { p = p->next; // 指向下一个节点 } p->next = (LRC *)malloc(sizeof(LRC)); // 为链表尾节点的 next 指针域分配内存 if (p->next == NULL) // 如果分配内存失败 { printf("歌词节点分配内存失败\n"); // 打印错误信息 perror("malloc"); // 打印错误信息 return NULL; // 返回 NULL } p->next->time = new_node.time; // 将新节点的时间点赋值给链表尾节点 strcpy(p->next->lrc_buf, new_node.lrc_buf); // 将新节点的歌词内容赋值给链表尾节点 p->next->next = NULL; // 将链表尾节点的 next 指针域置为 NULL return head; // 返回链表头节点 } LRC *search_lrc_node(LRC *head, int time) { LRC *p = head; // 定义临时指针变量 while (p != NULL) // 遍历链表 { if (p->time == time) // 找到指定时间点的歌词 { return p; // 返回歌词节点 } p = p->next; // 指向下一个节点 } return NULL; // 没有找到指定时间点的歌词 }