linux下C语言歌词解析(分文件)

main.c

#include<stdio.h>
#include<string.h>
#include <unistd.h>
#include<stdlib.h>
#include"code/start_mplayer.h"
#include"code/song_lrc.h"
#include"pos/console.h"

int main(int argc,char *argv[])
{
    
    //读取歌词文件
    char *arr = NULL; 
    LRC *head = NULL;
    arr = read_lrc(arr);
    set_bg_color(30);//设置字体背景色

    //按行切割
    char *buf[128]={arr,NULL};
	int i=0;
    cusor_hide();//隐藏光标
	while(1)//切割
	{
		buf[i] = strtok(buf[i],"\r\n");
		if(buf[i] == NULL)
			break;
		i++;
	}
    int n = i;//总行数
    clear_screen();//清屏
    //逐行分析
    head = analyse_row(head,buf,n);

    //启动mplayer
    mplayer_play("song/简单爱.mp3");
    
    //模拟时钟、滚屏、反显
    imitate_clock(head,n,buf);

    cusor_set_pos();//恢复光标位置
    cusor_show();//显示光标

    free(head);
    free(arr);
    return 0;
}

makefile

exec=main
cc=gcc
obj=main.o code/start_mplayer.o code/read_lrc.o code/lrc_link.o pos/console.o code/analyse_row.o code/imitate_clock.o#你要修改的地方
cflags=-Wall -g
$(exec):$(obj)
	$(cc) $^ -o $@ $(cflags)
%.o:%.c
	$(cc) -c $< -o $@ $(cflags)
clean:
	rm $(exec) *.o code/*.o pos/*.o 

code文件
analyse_row.c

#include<stdio.h>
#include<string.h>
#include "../pos/console.h"
#include"song_lrc.h"
LRC* analyse_row(LRC *head,char **buf,int n)
{
    int i = 0;
    for(i=0;i<n;i++)
    {   
        char c=0;
        sscanf(buf[i],"[%c:",&c);
        if(c>=48 && c<=57)
        {
            char *str_lrc = buf[i];
            while(*str_lrc=='[')
                str_lrc +=10;
            //strlrc 指向了歌词的位置

            char *str_time = buf[i];
            while(*str_time=='[')
            {
                int m = 0,s = 0;
                sscanf(str_time,"[%d:%d.80]",&m,&s);
                int time = m*60+s;

                LRC temp;
                temp.time=time;
                strcpy(temp.lrc,str_lrc);

                head = insert_link(head,temp);
                str_time +=10;
            }   
        }
        else
        {
            cusor_moveto(55,5+i);
            char tmp[128]="";
            char tmp1[128]="";
            sscanf(buf[i],"%*[^:]:%[^]]",tmp);
            sscanf(buf[i],"[%[^:]",tmp1);
            if(strcmp(tmp1,"ti")==0)
            {
                strcpy(tmp1,"歌名");
            }
            else if(strcmp(tmp1,"ar")==0)
            {
                 strcpy(tmp1,"歌手");
            }
            else if(strcmp(tmp1,"al")==0)
            {
                 strcpy(tmp1,"专辑");
            }
            else if(strcmp(tmp1,"by")==0)
            {
                 strcpy(tmp1,"制作");
            }
            set_fg_color(37);//设置字体前景色
            printf("%s: %s\n",tmp1,tmp);
        }
        
    }
    return head;
}

imitate_clock.c

#include<stdio.h>
#include<string.h>
#include <unistd.h>
#include"song_lrc.h"
#include"../pos/console.h"

void imitate_clock(LRC *head,int n,char **buf)//模拟时钟
{
    int t=0;
    int i=0;
    LRC *pi=NULL,*pf=NULL,*pr=NULL;

	while(t<266)
	{
        set_fg_color(37);//设置字体前景色
        cusor_moveto(79,23);
        printf("] %d:%d",4,25);//歌曲总时间
        cusor_moveto(38,23);
        printf("%02d:%02d [",t/60,t%60);//时钟
        fflush(stdout);
        int line =0;
        cusor_moveto(45,23);
        while(line<t)//进度条
        {
            printf(">");
            line +=8;
        }
       
        //到链表查询 
         LRC *ret = search_link(head,t);
         if(ret != NULL)
        {
            clear_screen();//清屏 
            for(i=0;i<n;i++)
            {   
                cusor_moveto(55,5+i);
                char b=0;
                sscanf(buf[i],"[%c:",&b);
                if(b<48 || b>57)
                {
                     char tmp[128]="";
                     char tmp1[128]="";
                     sscanf(buf[i],"%*[^:]:%[^]]",tmp);
                     sscanf(buf[i],"[%[^:]",tmp1);
                     if(strcmp(tmp1,"ti")==0)
                    {
                        strcpy(tmp1,"歌名");
                    }
                    else if(strcmp(tmp1,"ar")==0)
                    {
                          strcpy(tmp1,"歌手");
                    }
                    else if(strcmp(tmp1,"al")==0)
                    {
                         strcpy(tmp1,"专辑");
                    }
                    else if(strcmp(tmp1,"by")==0)
                    {
                         strcpy(tmp1,"制作");
                    }
                    printf("%s: %s\n",tmp1,tmp);
                }
            }
            cusor_moveto(79,23);
            printf("] %d:%d",4,25);//歌曲总时间
            cusor_moveto(38,23);
            printf("%02d:%02d [",t/60,t%60);//时钟
            fflush(stdout);
            cusor_moveto(45,23);
            int line1=0;
            while(line1<t)//进度条
            {
                printf(">");
                line1 +=8;
            }
            
            cusor_moveto(50,12);
            set_fg_color(37);//设置字体前景色
            if(pi!=NULL) 
            {
                printf("%s\n", pi->lrc);
            }
            cusor_moveto(50,13);
            set_fg_color(37);//设置字体前景色
            if(pr!=NULL)
            {
                pi=pr;
                printf("%s\n", pr->lrc);
            }
            cusor_moveto(50,14);
            set_fg_color(37);//设置字体前景色
            if(pf!=NULL)
            {
                pr=pf;
                printf("%s\n", pf->lrc);
            }
            cusor_moveto(50,15);
            set_fg_color(36);//设置字体前景色
            if(ret->lrc!=NULL)
            {
                pf=ret;
                printf("%s\n", ret->lrc);
            }
            for(i=0;ret->next!=NULL&&i<3;i++)
            {
                cusor_moveto(50,16+i);
                set_fg_color(37);//设置字体前景色
                printf("%s\n",ret->next->lrc);
                ret=ret->next;
            }
            
        }

     sleep(1);//休眠1s
     t++;   
	}
}

lrc_link.c

#include<stdio.h>
#include<stdlib.h>
#include"song_lrc.h"

LRC* insert_link(LRC *head,LRC tmp)//插入链表节点
{
	LRC *pi = NULL;
	pi = (LRC *)calloc(1,sizeof(LRC));//动态申请堆区空间
	if(pi == NULL)
	{
		perror("calloc");
		return NULL;
	}
	
	*pi = tmp;//把tmp的值赋值给pi
	pi->next = NULL;

	if(head == NULL)
	{
		head = pi;
		return head;
	}
	else
	{
		LRC *pb = head,*pf;
		while(pb->time<pi->time && pb->next!=NULL)
		{
			pf = pb;//pf保存pb的节点
			pb = pb->next;
		}
		if(pb->time>=pi->time)
		{
			if(pb==head)//头部插入
			{
				pi->next=head;
				head = pi;
				return head;
			}
			else//中部插入
			{
				pf->next=pi;
				pi->next=pb;
				return head;
			}
		}
		else
		{
			pb->next=pi;
			return head;
		}

	}
	return head;
}

LRC* search_link(LRC *head,int t)//搜索链表节点信息
{
	if(head == NULL)
	{
		printf("link not found\n");
		return NULL;
	}
	else
	{
		LRC *pb = head;
		while(t!=pb->time && pb->next!=NULL)
		{
			pb = pb->next;
		}
		if(t==pb->time)
		{
			return pb;
		}
		else
		{
			return NULL;
		}
		
	}

}

read_lrc.c

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

char* read_lrc(char *arr)
{
    long file_len = 0;
    FILE *fp = fopen("lrc/简单爱.lrc","r");
    if(fp==NULL)
    {
        perror("fopen");
        return NULL;
    }

    fseek(fp,0,2);//将文件流指针定义到文件末尾
    file_len=ftell(fp);//使用ftell计算文件的偏移量,文件的总大小

    rewind(fp);//复位文件流指针

    arr = (char *)calloc(1,file_len+1);
    if(arr==NULL)
    {
        perror("calloc");
        return NULL;
    }
        
    fread(arr,file_len,1,fp);//一次性 将文件数据 读入到 内存空间

    return arr;
    fclose(fp);
}
song_lrc.h

```c
#ifndef __SONG_LRC_H__
#define __SONG_LRC_H__


typedef struct lrc
{
    int time;
    char lrc[128];

    struct lrc *next;
}LRC;

extern char* read_lrc(char *arr);//读取歌词文件
extern LRC* insert_link(LRC *head,LRC tmp);//插入链表节点
extern LRC* search_link(LRC *head,int t);//搜索链表节点信息
extern LRC* analyse_row(LRC *head,char **buf,int n);//逐行分析
extern void imitate_clock(LRC *head,int n,char **buf);//模拟时钟

#endif

start_mplayer.c

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
//启动mplayer播放器 
//参数song_path 为歌曲的路径
void mplayer_play(char * song_path)
{
	pid_t pid;
	pid=fork();
	if(pid<0)
	{
		perror("fork");
	}
	else if(pid==0)
	{
		close(1);
		close(2);
		execlp("mplayer","mplayer","-slave","-quiet",song_path,NULL);
		exit(0);
	}
	else
		;
}

start_mplayer.h

#ifndef __START_MPLAYER_H__
#define __START_MPLAYER_H__
//启动mplayer播放器 
//参数song_path 为歌曲的路径
extern void mplayer_play(char * song_path);
#endif

pos文件
console.c

#include <stdio.h>
#include <stdlib.h>
#include "console.h"

void cusor_moveto(int x, int y)
{// ESC[y;xH
    printf("\033[%d;%dH",y,x);
    fflush(stdout);
} 

//保存光标位置
void cusor_get_pos(void)
{// ESC[s
    printf("\033[s");
    fflush(stdout);
} 

//恢复光标位置
void cusor_set_pos(void)
{// ESC[u
    printf("\033[u");
    fflush(stdout);
} 
void cusor_hide(void)
{
	printf("\033[?25l");
}
void cusor_show(void)//显示光标
{
	printf("\033[?25h");
}
//清屏
void clear_screen(void)
{// ESC[2J
    printf("\033[2J");
    fflush(stdout);
}

/*
COLOR_RED              红
COLOR_BLACK            黑
COLOR_GREEN            绿
COLOR_BLUE             蓝
COLOR_YELLOW           黄
COLOR_WHITE            白
COLOR_CYAN             青
COLOR_MAGENTA          洋红
*/
//设置前景颜色
void set_fg_color(int color)
{// ESC[#m
    printf("\033[%dm",color);
    fflush(stdout);
}

//设置背景颜色
void set_bg_color(int color)
{// ESC[#m
    printf("\033[%dm",(color+10));
    fflush(stdout);
}

console.h

#ifndef  _CONSOLE_H_
#define  _CONSOLE_H_

#define     COLOR_RED              31
#define     COLOR_BLACK            30
#define     COLOR_GREEN            32
#define     COLOR_BLUE             34
#define     COLOR_YELLOW           33
#define     COLOR_WHITE            37
#define     COLOR_CYAN             36
#define     COLOR_MAGENTA          35
/*
COLOR_RED              红
COLOR_BLACK            黑
COLOR_GREEN            绿
COLOR_BLUE             蓝
COLOR_YELLOW           黄
COLOR_WHITE            白
COLOR_CYAN             青
COLOR_MAGENTA          洋红
*/

extern void cusor_moveto(int x, int y);//光标跳转到 y行 x列
extern void cusor_get_pos(void);//保存光标位置
extern void cusor_hide(void);
extern void cusor_show(void);//显示光标
extern void cusor_set_pos(void);//恢复光标位置
extern void clear_screen(void);//清屏
extern void set_fg_color(int color);//设置字体前景色
extern void set_bg_color(int color);//设置字体背景色

#endif	//_CONSOLE_H_

歌词列表
lrc文件

[ti:简单爱]
[ar:周杰伦]
[al:范特西]
[by:大脸猫]
[00:04.41]周杰伦 Chow, Jay Jou
[00:10.56]简单爱(台视Star blue蓝星主题曲)
[00:18.48]词:徐若瑄 曲:周杰伦
[00:26.44]说不上为什么 我变得很主动
[00:31.37]若爱上一个人 什么都会值得去做
[02:04.94][00:36.09]我想大声宣布 对你依依不舍
[02:09.97][00:41.26]连隔壁邻居都猜到我现在的感受
[02:14.94][00:46.17]河边的风 在吹着头发 飘动
[02:19.80][00:51.25]牵着你的手 一阵莫名感动
[02:24.61][00:55.86]我想带你 回我的外婆家
[02:28.32][00:59.79]一起看着日落 一直到我们都睡着
[03:34.64][02:34.71][01:05.83]我想就这样牵着你的手不放开
[03:39.68][02:39.34][01:10.71]爱能不能够永远单纯没有悲哀
[03:44.27][02:43.90][01:15.44]我想 带你骑单车
[03:46.74][02:46.60][01:18.05]我想 和你看棒球
[03:49.77][02:49.58][01:20.71]想这样没担忧
[03:51.61][02:51.59][01:22.69]唱着歌 一直走☆
[03:54.38][02:54.35][01:25.57]我想就这样牵着你的手不放开
[03:59.19][02:59.01][01:30.41]爱可不可以简简单单没有伤害
[04:03.77][03:03.73][01:35.04]你 靠着我的肩膀
[04:06.33][03:06.26][01:37.49]你 在我胸口睡着
[04:09.13][03:09.34][01:40.57]像这样的生活
[04:11.36][03:11.26][01:42.66]我爱你 你爱我★
[03:13.76][01:44.97]想~~~ 简!简!单!单! 爱~~~
[03:23.61][01:54.30]想~~~ 简!简!单!单! 爱~~~

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值