pos3个文件11,942字节
4个目录171,449,978,880可用字节
Pos下有文件:
现将所有文件内容罗列于下,自行分开.c.h
Main.c
#include
#include
#include
#include
#include"lrc.h"
#include"./pos/console.h"
typedefstructtime
{//表示日期时间的数据结构
charminute;
charsecond;
}TIME;
TIMEm_time;//存储模拟时间
char*song_msg[4];//存储歌曲的信息
/*************************************************************************
*函数功能:
歌词解析器整体的控制
*参数:
无
*返回值:
无
**************************************************************************/
intmain()
{
intfile_length=0;//存储lrc文件内容的大小
char*file_buf=NULL;//指向malloc的空间,其中存放着lrc文件中所有的内容
char*lrc_text[200]={NULL};//指向,按照\r\n切割后的一行歌词
intlrc_line=0;//lrc文件中的行数
inti=0;
LRC*head=NULL,*p;//head记录歌词链表头
ints_time=0;//模拟时间变量
file_buf=read_src_file(&file_length,"./lrc/兰亭序.lrc");//从lrc文件中读出歌词内容
lrc_line=strtok_lrc_buf(lrc_text,file_buf);//按行切割歌曲内容
lrc_head_resolve(song_msg,lrc_text);//切割歌曲信息
print_song_message(song_msg);//显示歌曲信息
head=lrc_resolve(lrc_line,lrc_text);//保存时间:
歌词到链表中
//print(head);//遍历链表,用来测试链表
//ShellExecute(NULL,NULL,"TTPlayer.exe","兰亭序.mp3",NULL,1);//开启千千静听
m_time.second=0;
m_time.minute=0;
while
(1)//每秒钟到链表里面去找相应的歌词,如果找到那么就显示
{
/*
*1.定位光标,显示歌词
*/
GoToXY(20,5);
printf("%02d:
%02d",m_time.minute,m_time.second);
p=search(head,s_time);//到连表里查找当前时间点对应的歌词,如果有那么就返回歌词的首地址
if(p!
=NULL)
{
lrc_show(p);
}
/*
*1.运行模拟时间
*/
Sleep(500);//延时,注意在windows平台Sleep
(1);延时1毫秒
s_time=s_time+1;
++m_time.second;
if(m_time.second==60)
{
m_time.second=0;
++m_time.minute;
if(m_time.minute==60)
m_time.minute=0;
}
}
return0;
}
/*****************************************************************************/
lrc.h
#ifndef__LRC_H__
#define__LRC_H__
typedefstructlrc{
inttime;
charlrc_buf[200];
structlrc*next;
}LRC;
externchar*read_src_file(int*file_length,char*src_file_name);
externintstrtok_lrc_buf(char*lrc_text[],char*file_buf);
externvoidlrc_head_resolve(char*lrc_head_info[],char*lrc_text[]);
externvoidprint_song_message(char*msg_info[]);
externLRC*lrc_resolve(intlrc_line,char*lrc_text[]);
externLRC*InsertList(LRC*head,LRC*lrc_link);
externvoidprint(LRC*head);
externLRC*search(LRC*head,inttime);
externvoidlrc_show(LRC*pi);
externvoidprint_lrc(char*lrc);
#endif
/*****************************************************************************/
lrc.c
#include
#include
#include
#include
#include"lrc.h"
#include"./pos/console.h"
/*************************************************************************
*函数功能:
读出文件内容
*参数:
*file_length:
整型指针,此地址中保存文件字节数。
*src_file_name:
文件名字,从此文件中读取内容。
*返回值:
读出字符串的首地址
**************************************************************************/
char*read_src_file(int*file_length,char*src_file_name)
{
unsignedlongintFILE_SIZE=0;
char*src_file_text=NULL;
FILE*fp=NULL;
fp=fopen(src_file_name,"rb");
if(fp==NULL)
{
printf("open%sfaild\n",src_file_name);
return0;
}
fseek(fp,0,SEEK_END);
FILE_SIZE=ftell(fp);
*file_length=FILE_SIZE;//返回歌词文件内容的大小
rewind(fp);//一定要把“文件指针”移动到文件开始处
src_file_text=(char*)malloc(FILE_SIZE);
if(fread(src_file_text,FILE_SIZE,1,fp)==0)
{
printf("readfromsrc_filefaild\n");
returnNULL;
}
fclose(fp);//关闭文件
returnsrc_file_text;
}
/************************************************************************
*函数功能:
切割歌词数组
*参数:
*lrc_text指针数组,让其指针指向切出来的内容
*file_buf歌词内容数组
*返回值:
切割出来的字符串的个数
*************************************************************************/
intstrtok_lrc_buf(char*lrc_text[],char*file_buf)
{
inti=0;
lrc_text[i++]=strtok(file_buf,"\r\n");
while((lrc_text[i++]=strtok(NULL,"\r\n"))!
=NULL);
returni;
}
/**************************************************************************
*函数功能:
解析lrc前四行,歌曲的信息如歌手、专辑等。
。
*参数:
*lrc_text指针数组lrc中的前四行
*song_msg指针数组用来指向处理好的歌曲信息
*返回值:
无
**************************************************************************/
voidlrc_head_resolve(char*song_msg[],char*lrc_text[])
{
inti=0;
char*message[]={"[ti","[ar","[al","[by"};
char*temp;
for(i=0;i<4;i++)//循环四次找到四个头信息的开始
{
if(strncmp(lrc_text[i],message[i],3)==0)
{
temp=lrc_text[i];
/*
[ti:
兰亭序]
[ar:
李维]
[al:
情已逝DSD]
[by:
朱古力]
*/
while(*temp!
=']')//找到头信息],然后改为'\0'
{
temp++;
}
*temp='\0';
song_msg[i]=lrc_text[i]+4;//跳过ti:
三个字母,保存歌词信息;
}
}
}
/**************************************************************************
*函数功能:
打印歌曲信息
*参数:
*song_msg歌曲信息指针数组指向歌曲头信息内容
*返回值:
无
*注意点:
无
**************************************************************************/
voidprint_song_message(char*song_msg[])
{
inti=0;
char*name[4]={"歌名:
","歌手:
","专辑:
","制作:
"};
for(i=0;i<4;i++)
{
printf("%s%s\n",name[i],song_msg[i]);
}
}
/**************************************************************************
*函数功能:
解析歌曲信息
*参数:
*lrc_text指向歌词内容(以行的方式存储)的指针数组
*lrc_line歌词的行数
*返回值:
无
**************************************************************************/
LRC*lrc_resolve(intlrc_line,char*lrc_text[])
{
LRC*head=NULL,*lrc_link;
inti=0,j=0,CurOffset;
char*LrcFile;
intCurTime[10];//用来暂时记录歌词中的时间,单位为:
毫秒
intnum=0;//用来暂时记录本句歌词有多少个时间与其对应
for(i=4;i{
LrcFile=lrc_text[i];//一行的歌词:
[00:
25.21]兰亭临帖行书如行云流水
CurOffset=1;//标识时间位置的偏移量
if((LrcFile[CurOffset])>='0'&&(LrcFile[CurOffset])<='9')//检测到歌词时间标签
{
char*lrc;//用来暂时记录时间后面的歌词
num=0;//解析每句歌词时,要把本句歌词对应的时间数初始化为0
//[00:
25.21]兰亭临帖行书如行云流水
//[02:
04.94][00:
36.09]我想大声宣布对你依依不舍
while(LrcFile[CurOffset]>='0'&&LrcFile[CurOffset]<='9')//取出这句歌词所有时间标签
{
CurTime[num++]=(((LrcFile[CurOffset]-'0')*10+(LrcFile[CurOffset+1]-'0'))*60+((LrcFile[CurOffset+3]-'0')*10+LrcFile[CurOffset+4]-'0'))*1000+\
(LrcFile[CurOffset+6]-'0')*100+(LrcFile[CurOffset+7]-'0')*10;
CurOffset=CurOffset+10;//解析一句歌词在不同时间出现的情况时,需要把指针往后偏移10
}
//lrc=&LrcFile[CurOffset-1];//得到这句歌词首地址“我想大声宣布对你依依不舍”
lrc=LrcFile+10;
//根据本句歌词对应的时间个数,把歌词与时间保存到链表中
for(j=0;j{
lrc_link=(LRC*)malloc(sizeof(LRC));//申请节点,存放解析出歌词与时间
lrc_link->time=CurTime[j];
strcpy(lrc_link->lrc_buf,lrc);
//将解析出的时间、歌词内容插入到单向链表并进行排序
head=InsertList(head,lrc_link);
}
}
}
returnhead;
}
/**************************************************************************
*函数功能:
往链表中插入歌词节点。
*参数:
*head链表的头节点地址。
*lrc_link将要插入的节点首地址。
*返回值:
插入之后链表的头节点的地址
**************************************************************************/
LRC*InsertList(LRC*head,LRC*lrc_link)
{
LRC*pb,*pf;
if(head==NULL)//如果原先链表为空head为pi
{
lrc_link->next=NULL;
head=lrc_link;
returnhead;
}
pb=pf=head;
while((lrc_link->time>pb->time)&&(pb->next!
=NULL))//查找比pi->num更大的节点
{
pf=pb;
pb=pb->next;
}
if(lrc_link->time<=pb->time)//如果上面的while循环式因为找到lrc_link->time<=pb->time而推出的
{
if(pb==head)//如果找到的节点为第一个,则pi应该放到head的前面
{
lrc_link->next=head;//把pi放到链表里
head=lrc_link;//把pi变成头节点
}
else//如果是pb普通节点的话在pf和pb之间插入pi
{
pf->next=lrc_link;//pb的前一个节点的指针域指向pi
lrc_link->next=pb;//pi的指针域指向pb
}
}
else//如果链表中的节点的time都比pi->time小,则插到链表尾端
{
pb->next=lrc_link;//pb的指针域指向pi
lrc_link->next=NULL;//pi的下一个为NULL即pi为链表的尾
}
returnhead;
}
/**************************************************************************
*函数功能:
从歌词链表中查找时间为time的结点
*参数:
*head链表的头节点地址。
*time要查询的时间
*返回值:
时间为time的结点的首地址
**************************************************************************/
LRC*search(LRC*head,inttime)//在一个已建立的链表中查找某一节点
{
LRC*p,*pi=NULL;
p=head;//导入已存在链表的头文件
while((p->time/1000)!
=time&&p->next!
=NULL)//判断是否找到要找的数据,判断是否到链表尾。
{
p=p->next;//不是要找的结点后移一步
}
if((p->time/1000)==time)
{
pi=p;//找到数据则返回相应指针地址
}
elseif(p->next==NULL)//到链表尾则打印数据未找到
pi=NULL;
returnpi;
}
/**************************************************************************
*函数功能:
遍历链表
*参数:
*head链表的头节点地址。
*返回值:
无
**************************************************************************/
voidprint(LRC*head)
{
printf("\n链表所有信息如下:
\n");
printf("TIME\t\tLRC_BUF\n");
while(head!
=NULL)
{
printf("%d\t\t%s\n",head->time,head->lrc_buf);
head=head->next;
}
printf("\n");
}
typedefstructtime
{//表示日期时间的数据结构
charminute;
charsecond;
}TIME;
externTIMEm_time;
externchar*song_msg[4];
charlrc_buf[6][200]={""};
/**************************************************************************
*函数功能:
歌词显示
*参数:
*pi新查找到得结点
*返回值:
无
**************************************************************************/
voidlrc_show(LRC*pi)
{
staticintx=0,y=11;
staticintlrc_num=0;
inti=0;
if(lrc_num<6)
{
/*
*1:
前6行歌词显示的方式
*2:
*/
strcpy(lrc_buf[lrc_num],pi->lrc_buf);//lrc_num=0、1、2、3、4、5
if(lrc_num>0)
{
GoToXY(x,y-1);
printf("%s\n",lrc_buf[lrc_num-1]);//只覆盖上1次显示绿颜色的那一行歌词
}
GoToXY(x,y);
print_lrc(pi->lrc_buf);//当