qfedu-c-level/lyric_analysis/srcs/lrc.c

86 lines
3.4 KiB
C

#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; // 没有找到指定时间点的歌词
}