1.main.c文件
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <unistd.h>//休眠所需的头文件
#include "./pos/console.h"//光标使用所需的头文件
#include "lrc.h"
#include "./mplayer/start_mplayer.h"//播放歌曲的头文件
int main(int argc, char const *argv[])
{
ontime time = {0,0,0};
char *text = get_data();
char *list[50];
int num = cut_text(text,list);
showsong(list);
jay *head = songword(num,list);
free(text);
showtime(time);
showsongtxt(head,NULL);
mplayer_play("./music/简单爱.mp3");
jay *pd = head;
int t = 0;
while(1)
{
int m = t / 60;
int s = t % 60;
time.m = m;
time.s = s;
showtime(time);
pd = findspot(head,t);
if (pd != NULL)
{
showsong(list);
showtime(time);
jay *h = findstartspot(pd);
showsongtxt(h,pd);
if (pd -> n == NULL)
{
break;
}
}
sleep(1);
//时间+1
t++;
}
free_link(head);//释放链表
cusor_show();//显示光标
return 0;
}
2.lrc.c文件
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "./pos/console.h"
#include "lrc.h"
char *get_data()
{
FILE *f = fopen("./text/简单爱.lrc", "r");
if (f == NULL)
{
printf("文件打开失败\n");
return NULL;
}
fseek(f, 0, SEEK_END);
long len = ftell(f);
rewind(f);
char *lrc = malloc(len + 1);
fread(lrc, len, 1, f);
fclose(f);
return lrc;
}
int cut_text(char *str, char *list[])
{
int i = 0;
list[i] = strtok(str, "\r\n");
// printf("%s\n",list[i]);
while (1)
{
list[++i] = strtok(NULL, "\r\n");
if (list[i] == NULL)
{
break;
}
}
return i;
}
void showsong(char *list[])
{
clear_screen();
cusor_hide();
char buf[4][50];
for (int i = 0; i < 4; i++)
{
cusor_moveto(40, i + 1); // 光标移到 第0行,第40列
set_fg_color(COLOR_RED);
sscanf(list[i], "%*4c%[^]]", buf[i]);
// printf("%s\n",buf[i]);
}
}
jay *songword(int num, char *list[])
{
jay *head = NULL, *newhead = NULL;
int m, s, ms;
int timespot[10];
int timenums = 0;
char *str;
for (int i = 4; i < num; i++)
{
str = list[i];
timenums = 0;
while (*str == '[')
{
sscanf(str, "[%2d:%2d.%2d", &m, &s, &ms);
timespot[timenums] = m * 60 + s;
timenums++;
str = str + 10;
}
for (int j = 0; j < timenums; j++)
{
newhead = malloc(sizeof(jay));
newhead->time = timespot[j];
strcpy(newhead->buf_num, str);
newhead->n = NULL;
if (head == NULL)
{
head = newhead;
head->l = NULL;
head->n = NULL;
}
else
{
jay *myh = head;
while (newhead->time >= myh->time && myh->n != NULL)
{
myh = myh->n;
}
if (myh->time > newhead->time)
{
if (myh == head) // 当前myh为new的下一个节点或者是最后一个节点
{
newhead->l = NULL;
newhead->n = head;
head->l = newhead;
head = newhead;
}
else // 当前myh为中间节点
{
// myh->l = head;
// head->n = newhead;
// myh = newhead;
// newhead->n = newhead;
// myh->n = NULL;
jay *l = myh->l;
l->n = newhead;
newhead->l = l;
newhead->n = myh;
myh->l = newhead;
}
}
else // 当前myh为第一个节点
{
newhead->l = myh;
myh->n = newhead;
}
}
}
}
// jay * mmm = head;
// while(mmm->n != NULL){
// printf("%d,%s\n",mmm->time,mmm->buf_num);
// mmm = mmm->n;
// }
return head;
}
void showtime(ontime time) // 展示时间
{
char time_num[30];
sprintf(time_num, "%2d:%2d.%2d", time.m, time.s, time.ms);
color_pos_printf(time_num, 39, 5, COLOR_GREEN);
}
void showsongtxt(jay *start, jay *pd) // pd为记录的当前节点,start记录的是开始节点--获取歌词
{
char time_txt[30];
for (int i = 0; i < 5; i++)
{
if (start == pd)
{
color_pos_printf(start->buf_num, 30, 6 + i, COLOR_MAGENTA);
}
else
{
color_pos_printf(start->buf_num, 30, 6 + i, COLOR_YELLOW);
}
start = start->n;
}
}
jay *findspot(jay *lrc, int time) // lrc为头节点,time为时间 --获取节点
{
while (lrc != NULL)
{
if (lrc->time == time)
{
return lrc;
}
else
{
lrc = lrc->n;
}
}
return NULL;
}
jay *findstartspot(jay *lrc) // 寻找开始节点,lrc记录当前节点
{
// if(lrc->l == NULL)
// {
// return lrc;
// }
// else if(lrc->l->l == NULL)
// {
// return lrc->l;
// }
// else if(lrc->l->l->l == NULL)
// {
// return lrc->l->l;
// }
// else if(lrc->l->l->l->l == NULL)
// {
// return lrc->l->l->l;
// }
// else if(lrc->l->l->l->l->l == NULL)
// {
// return lrc->l->l->l->l;
// }
if (lrc->l == NULL)
{
return lrc;
}
// 如果当前节点为第二个节点,那么第一个节点就是开始节点
else if (lrc->l->l == NULL)
{
return lrc->l;
}
// 如果当前节点是最后一个节点,那么其上级的上级的上级的上级为开始节点
else if (lrc->n == NULL)
{
return lrc->l->l->l->l;
}
// 如果当前节点为倒数第二个节点,那么其上级的上级的上级为开始节点
else if (lrc->n->n == NULL)
{
return lrc->l->l->l;
}
// 如果当前节点为3~倒数第三个节点中的某个节点,返回当前节点的上级的上级为开
else
{
return lrc->l->l;
}
}
void color_pos_printf(char *str, int x, int y, int color)
{
cusor_moveto(x, y);
set_fg_color(color);
printf("%s\n", str);
}
void free_link(jay *head)
{
while (head != NULL)
{
if (head->n != NULL)
{
jay *myh = head->n;
free(head);
head = myh;
}
else
{
free(head);
head = NULL;
}
}
}
3.lrc.h文件
#ifndef MY_LRC
#define MY_LRC
typedef struct time
{
int m;
int s;
int ms;
}ontime;
typedef struct jaychou
{
int time;
char buf_num[50];
struct jaychou *l;
struct jaychou *n;
}jay;
extern char *get_data();
extern int cut_text(char *str,char *list[]);
extern void showsong(char *list[]) ;
extern jay *songword(int num,char *list[]);
extern void color_pos_printf(char *str,int x,int y ,int color);
extern void showtime(ontime time);
extern void showsongtxt(jay *start,jay *pd);
extern jay* findspot(jay *lrc,int time);
extern jay *findstartspot(jay *lrc);
#endif
4.makefile文件
EXEC = main;
OBJ = main.o lrc.o ./pos/console.o ./mplayer/start_mplayer.o;
FLAGS = -wall -g;
CC = gcc;
$(EXEC) :(OBJ)
$(CC) $(OBJ) -o $(EXEC) $(FLAGS);
%.o:%.c %.h
$(CC) -c $< -o $@
clear:
rm $(EXEC) *.o
提示;其他要用的的文件放在资源里面了
示例图