vc 用结构体实现对歌词lrc的读取和显示

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>


#define LRCLINENUM    100          //宏定义每行的歌词数量
#define LRCLINEMSGNUM 130
#define WORDNUM       10
#define OK            1 //成功的返回值
#define ERROR         0 //失败的返回值




typedef struct LRC
{
char lrc[LRCLINENUM];                           
unsigned int lrc_time;
struct LRC *next;
};//定义歌词的结构体   lrc[LRCLINENUM]为每行的歌词,lrc_time为整形的时间量, 


struct LRC *head = NULL;


/******************************************************************************************* 
函数:FILE *open_file(char *file_name)
功能:打开歌词文件 若成功返回文件描述符fp 失败返回 NULL
参数:歌词文件名 file_name
返回值:FILE *
********************************************************************************************/
FILE *open_file(char *file_name)
{
FILE *fp;                        //定义文件描述符指针
fp = fopen(file_name, "r+");     //以只读方式打开
if(fp == NULL)
{
printf("file open error\n");
return NULL; //失败返回NULL
}
else 
return fp;
}


/******************************************************************************************* 
函数:int get_lrcnum(char *file_name)
功能:打开歌词文件 若成功代表将返回歌词数量 失败返回ERROR 
参数:歌词文件名 file_name
返回值:int
********************************************************************************************/
int get_lrcnum(char *file_name)
{
int lrc_num;//定义歌词数量变量
FILE *fp;
fp = open_file(file_name);  //打开文件
lrc_num = fseek(fp , 0 , 2);//将光标移到文件末尾   
if(lrc_num < 0)
{
printf("fseek error\n");
fclose(fp);
return ERROR;           //失败判断
}
lrc_num = ftell(fp); //读出光标位置
if(lrc_num < 0)
{
fclose(fp);
return ERROR; //失败判断
}
else
{
fclose(fp);             //关闭文件
return lrc_num;
}
}


/******************************************************************************************* 
函数:char *get_file_to_str(char *file_name)
功能:打开歌词文件 若成功返回代表将歌词数量 失败返回NULL
参数:歌词文件名 file_name
返回值:char *   //若用此函数 注意释放返回的指针
********************************************************************************************/
char *get_file_to_str(char *file_name)
{
char *str = NULL;
int temp_num;
int lrc_num;
FILE *fp;
fp = open_file(file_name);                //打开文件
lrc_num = get_lrcnum(file_name);          //获得文件歌词数目
str = (char *)malloc(lrc_num);            //申请空间
//if(str ==NULL)
temp_num = fread(str,lrc_num,1,fp);

//printf("temp_num = %d\n",temp_num);
//printf("lrc_num = %d\n",lrc_num);
// if(temp_num != lrc_num)
// {
// printf("fread error\n");
// fclose(fp);
// return NULL;
// }
// else
// {
fclose(fp);
return str;
//}
}


/******************************************************************************************* 
函数:int get_Allline_num(char *file_name)
功能:获得歌词一共多少行 若成功返回行的数量 失败返回error
参数:歌词文件名 file_name
返回值:int
********************************************************************************************/
int get_Allline_num(char *file_name)
{
char *str,*temp_flag;
char *delim = "\r\n";
int allline_num = 0;
str = get_file_to_str(file_name);
temp_flag = strtok(str,delim);
if(temp_flag == NULL)
{
printf("not have strtok\n");
free(str);
return ERROR;
}
else
{
allline_num++;
while((temp_flag = strtok(NULL,delim)) != NULL)
{
allline_num++;
}
free(str);
return allline_num;
}
}


/******************************************************************************************* 
函数:char *get_line_msg(char *file_name, int line_num)
功能:获得歌词每行的信息 若成功返回每行信息的指针 失败返回NULL
参数:歌词文件名 file_name,第几行的line_num
返回值:char *
********************************************************************************************/
char *get_line_msg(char *file_name,int line_num,char *line_msg)
{
char *str;
int temp_num = 0,allline_num;
char *delim = "\r\n";
memset(line_msg,0,LRCLINEMSGNUM);
allline_num = get_Allline_num(file_name);
if(line_num > allline_num)
{
printf("line_num is too big\n");
return NULL;
}
str = get_file_to_str(file_name);
strcpy(line_msg, strtok(str,delim));
if(line_msg == NULL)
{
printf("get_msg not have strtok\n");
free(str);
return NULL;
}
else
{
if(temp_num == line_num)
{
free(str);
return line_msg;
}
temp_num++;
memset(line_msg,0,LRCLINEMSGNUM);
while((strcpy(line_msg, strtok(NULL,delim))) != NULL)
{
if(temp_num == line_num)
{
free(str);
return line_msg;
}
temp_num++;
memset(line_msg,0,LRCLINEMSGNUM);
}
}
free(str);
return NULL;
}


/******************************************************************************************* 
函数:int dealisnotlrc_part(char *line_msg)
功能:处理歌词文件中非歌词部分 若成功返回OK 失败返回ERROR
参数:歌词行信息 line_msg
返回值:int
********************************************************************************************/
int dealisnotlrc_part(char *line_msg)
{
if(*line_msg == '[' && *(line_msg+1) == 't' && *(line_msg+2) == 'i' && *(line_msg+3) == ':')
{
*(line_msg+strlen(line_msg)-1) = '\0';
printf("%s\n",line_msg+4);
Sleep(1000);
return OK;
}
else if(*line_msg == '[' && *(line_msg+1) == 'a' && *(line_msg+2) == 'r' && *(line_msg+3) == ':')
{
*(line_msg+strlen(line_msg)-1) = '\0';
printf("%s\n",line_msg+4);
Sleep(1000);
return OK;
}
else if(*line_msg == '[' && *(line_msg+1) == 'a' && *(line_msg+2) == 'l' && *(line_msg+3) == ':')
{
*(line_msg+strlen(line_msg)-1) = '\0';
printf("%s\n",line_msg+4);
Sleep(1000);
return OK;
}
else if(*line_msg == '[' && *(line_msg+1) == 'b' && *(line_msg+2) == 'y' && *(line_msg+3) == ':')
{
*(line_msg+strlen(line_msg)-2) = '\0';
printf("%s\n",line_msg+4);
Sleep(1000);
return OK;
}
else
return ERROR;
}


/******************************************************************************************* 
函数:int get_lrc_part(char *time)
功能:处理歌lrc 中时间,将时间从字符型转换为整形 若成功返回整形的时间 失败返回ERROR
参数:歌词行信息 的字符时间
返回值:int
********************************************************************************************/
int get_lrc_part(char *time)
{
int deal_time = 0;
if(*time >= '0' && *time <= '9' && *(time+1) >= '0' && *(time+1)  <= '9' && *(time+2) ==':'
&& *(time+3) >= '0' && *(time+3)  <= '9' &&*(time+4) >= '0' && *(time+4)  <= '9' && *(time+5) =='.'
&& *(time+1) >= '0' && *(time+1)  <= '9' &&*(time+1) >= '0' && *(time+1)  <= '9')
{
deal_time = (*time-'0')*600 + (*(time+1)-'0')*60 + (*(time+3)-'0')*10 +(*(time+4)-'0');
return deal_time;
}
else
return ERROR;

}


/******************************************************************************************* 
函数:struct LRC *lrc_addlink(int time, char *lrc)
功能:将处理过歌词和时间放入的链表 若成功返回head 失败返回NULL
参数:时间lrc_time 歌词指针lrc
返回值:struct LRC *
********************************************************************************************/
struct LRC *lrc_addlink(int lrc_time, char *lrc)
{
struct LRC *pb,*pf;
pb = head;
if(pb == NULL)
{
head = (struct LRC *)malloc(sizeof(struct LRC));
if(head == NULL)
{
printf("head ask for space fail\n");
return NULL;
}
else
{
head->lrc_time = lrc_time;
strcpy(head->lrc,lrc);
head->next = NULL;
}
}
else
{
while(pb != NULL)
{
pf = pb;
pb = pb->next;
}
pb = (struct LRC *)malloc(sizeof(struct LRC));
if(pb == NULL)
{
printf("pb ask for space fail\n");
return NULL;
}
pb->lrc_time = lrc_time;
strcpy(pb->lrc,lrc);
pf->next = pb;
pb->next = NULL;
}
return head;
}


/******************************************************************************************* 
函数:void lrc_linkprint(struct LRC *head)
功能:将处理过歌词和时间放入的链表后输出
参数:歌词头head
返回值:void
********************************************************************************************/


void lrc_linkprint(struct LRC *head)
{
struct LRC *pb;
pb = head;
if(pb == NULL)
{
printf("not create link\n");
return;
}
else
{
while(pb != NULL)
{
Sleep(1000);
printf("%s\n",pb->lrc);
pb = pb->next;
}
}
}


/******************************************************************************************* 
函数:void lrc_linkorder(struct LRC **head)
功能:将处理过歌词和时间放入的链表后进行排序
参数:歌词头head的二重指针
返回值:void
********************************************************************************************/
void lrc_linkorder(struct LRC **head)
{
struct LRC *pb,**array,*temp;
int i=0,j,k;
pb = *head;
while(pb != NULL)
{
i++;
pb = pb->next;
}
array =( struct LRC**)calloc(i,sizeof(struct LRC));
pb = *head;
for(j=0;j<i;j++)
{
*(array+j) = pb;
pb=pb->next;
}
for(j=0;j<i-1;j++)//按照各链表元素的id从小到大排序,将各元素放入指针数组中
{
for(k=j+1;k<i;k++)
{
if((*(array+j))->lrc_time > (*(array+k))->lrc_time)
{
temp = *(array+k);
*(array+k) = *(array+j);
*(array+j)= temp;
}
}
}
*head = *array;
for(j=0;j<i-1;j++) //按照指针数组中的各链表元素的地址的顺序重新给链表安排指针域
{
(*(array+j))->next = *(array+j+1);
}
(*(array+i-1))->next = NULL;




}


/******************************************************************************************* 
函数:char *get_lrc_part(char *line_msg)
功能:处理歌词文件中歌词部分 将msg中的时间和歌词放入链表 若成功返回OK 失败返回ERROR
参数:歌词行信息 line_msg
返回值:char *
********************************************************************************************/
char *deal_lrc_part(char *line_msg)
{
char *lrc[WORDNUM];
char *delim = "[]";
int i = 0,j = 0,lrc_time;
lrc[0] = strtok(line_msg,delim);
if(lrc[0] == NULL)
{
printf("not have lrc\n");
return NULL;
}
else
{
i++;
while((lrc[i] = strtok(NULL,delim)) != NULL )
{
i++;
}
for(j=0;j<i-1;j++)
{
lrc_time = get_lrc_part(lrc[j]);
if(lrc_time > 0)
{
//printf("lrc_time is %d,lrc is %s\n", lrc_time,lrc[i-1]);
lrc_addlink(lrc_time, lrc[i-1]);
}
}

return lrc[i-1];
}
}






int main()
{
char *line_msg,*lrc;
int allline_num = 0,line_num;
char *file_name = "发如雪.lrc";
line_msg = (char *)malloc(LRCLINEMSGNUM);
allline_num = get_Allline_num(file_name);
for(line_num=0;line_num<allline_num;line_num++)
{
get_line_msg(file_name,line_num,line_msg);
if( (dealisnotlrc_part(line_msg) ) != OK)
{
lrc = deal_lrc_part(line_msg);
}
}
lrc_linkorder(&head);
lrc_linkprint(head);
free(line_msg);
return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值