歌词解析器代码详情.docx

上传人:b****5 文档编号:8762369 上传时间:2023-02-01 格式:DOCX 页数:18 大小:24.71KB
下载 相关 举报
歌词解析器代码详情.docx_第1页
第1页 / 共18页
歌词解析器代码详情.docx_第2页
第2页 / 共18页
歌词解析器代码详情.docx_第3页
第3页 / 共18页
歌词解析器代码详情.docx_第4页
第4页 / 共18页
歌词解析器代码详情.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

歌词解析器代码详情.docx

《歌词解析器代码详情.docx》由会员分享,可在线阅读,更多相关《歌词解析器代码详情.docx(18页珍藏版)》请在冰豆网上搜索。

歌词解析器代码详情.docx

歌词解析器代码详情

共6个文件,一个文件夹。

Dir目录如下。

驱动器F中的卷没有标签。

卷的序列号是18A6-FCB5

F:

\W.E\C语言编程\歌词解析器的目录

2013-01-2216:

27

.

2013-01-2216:

27

..

2013-01-2216:

27

lrc

2012-11-1915:

299,215lrc.c

2011-12-1212:

17644lrc.h

2012-09-2415:

182,083main.c

2013-01-2216:

27

pos

3个文件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);//当

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 工学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1