用c语言来简单制作歌曲界面,让c不在枯燥~各位官爷快来围观吧

一、效果显示

在这里插入图片描述

二、操作流程

各位官爷,看到这么可爱的皮卡丘有没有心动呐,哈哈哈,赶快加入打包带走吧,不废话了,来,上干货~
想直接看原码的可去代码原文件查看哦
1、流程分析
a、先将歌词读取内当中;
用fopen打开歌词文件 FILE *fp = fopen(“简单爱.lrc”, “r”);
使用fseek将文件流指针 定位到文件尾部 获得文件总大小;
使用rewind 复位文件流置针
根据文件总大小 从堆区 申请 合适的空间 char *arr ;
使用fread 读取文件数据 到内存中 arr;
关闭文件;
b、将提取出的内存数据 按行"\r\n"切割 存入 字符指针数组 char *buf[128]={NULL};(window下换行符由\r\n组成呦)
提取结束后记得保存一下行数,后期用的到呐;
c、逐行分析,分别提取对应的时间和歌词内容
[1]、为降低难度,咱们将歌词分开,先分析前四行

在这里插入图片描述
原数据:
[ti:简单爱]
[ar:周杰伦]
[al:范特西]
[by:大脸猫]
那如何实现上述效果呐,各位官爷请看我的表演:

char tmp[4][128];
int i=0;
for(i=0;i<4;i++)
    {
        sscanf(buf[i],"%*[^:]:%[^]]",tmp[i]);
    }    
    clear_screen();
 cusor_moveto(10,2);
    printf("歌名:%s\n",tmp[0]);
 cusor_moveto(10,3);
    printf("歌手:%s\n",tmp[1]);
 cusor_moveto(10,4);
    printf("专辑:%s\n",tmp[2]);
 cusor_moveto(10,5);
    printf("制作:%s\n",tmp[3]);

hhh,一顿操作猛如虎,一看战绩0-5 !
[2]、逐行分析剩下的行 将时间+歌词 一一对应 插入链表
先设计一个简单的链表:

typedef struct lrc{    
	//数据域    
	int time;    
	char lrc[128];        
	//指针域    
	struct lrc *next;
}LRC;

是心动吗~哈哈,皮一下
接下来时间和歌词插入

LRC tmp;
 int i=4;
   
    for(i=4;i<num;i++)
    {
        char *str_lrc=buf[i];//获取歌词
        
        while(*str_lrc=='[')
            str_lrc+=10;
            char *str_time=buf[i]//获取时间
            while(*str_time=='[')
        {
            int m=0,s=0;
            sscanf(str_time,"[%d:%d:%*d]",&m,&s);
            int time =m*60+s;//将时间转为数值,方便后面比较
            tmp.time=time;
            strcpy(tmp.lrc,str_lrc);
             head=insert_link(head,tmp);//创建链表
              str_time+=10;
        }
        
    }
            

完成一半喽,此处建议打印一下链表,修改一下出现的buf,整装待发,咱们继续~
d、模拟时钟,让时间走起来吧
给各位官爷一串模拟时钟代码,有时间和想法可以研究一下呐,下面用到的几乎一样

#include <stdio.h>
int main(int argc, char *argv[])
{		
	int i=0;	
	while(1)	
	{         
	printf("\r%02d:%02d",i/60,i%60);         				   		
	fflush(stdout);         
	//到链表查询          
	LRC *ret = search_link(head,i);         	
	if(ret != NULL)         
	{             
	printf("%s\n", ret->lrc);         
	}                           
	sleep(1);//休眠1s         
	i++;	
	}		
	return 0;
}

e、让歌词滚屏(光标定位)
f、给歌词添加颜色。//皮肤丝滑有活力~哈哈哈
g、启动音乐
h、释放申请的动态空间,谁污染谁治理原理,咳咳,做一个负责的好公民。
为方便各位官爷查看,我把这几部分代码直接放到总代码区,下面有请~

代码原文件

main.c文件

#include<stdio.h>
#include "start_mplayer.h"
#include"fun.h"
#include<string.h>
int main(int argc, char const *argv[])
{
    char *arr=NULL;
    //将歌词内容提取到内存中
    FILE *fp=fopen("简单爱.lrc","r");
    arr=read_file(fp);
    char *buf[128]={arr};
    //歌词切割    
    int i=0;    	
    while((buf[i++]=strtok(buf[i],"\r\n")));    
    int num=i-1;
    //打印前四行    
    //char *lrc=NULL;    
    printf_link1(buf);
    //打印剩余歌词    
    LRC *head=NULL;    
    head=printf_link2(head, buf,num);
    //printf_link(head);
    //模拟时钟,歌词的滚屏,反显,启动音乐
    clock_lnk(head);
    free_link(head);
    return 0;}

    

fun.c文件

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include"fun.h"
#include "start_mplayer.h"
#include"console.h"

char *read_file(FILE *fp)//将歌词读取到内存
{  
	char *file_data=NULL;
    if(fp==NULL)    
    {        
    perror("fopen");        
    return NULL;    
    } 
    //判断文件大小
    fseek(fp,0,2);    
    long file_len=ftell(fp);    
    rewind(fp);
    //申请动态空间
    file_data=(char*)calloc(1,file_len+1);    
    if(file_data==NULL)    
    {        
    perror("calloc");        
    return NULL;         
    }  
    fread(file_data,file_len ,1,fp);
    fclose(fp);       
    return file_data;
    }
void printf_link1(char *buf[])//提取前四行歌词
{    
	char tmp[4][128];    
	int i=0;        
	for(i=0;i<4;i++)    
	{        		
	sscanf(buf[i],"%*[^:]:%[^]]",tmp[i]);    
	}        
	clear_screen();    
	cusor_moveto(10,2);

	printf("歌名:%s\n",tmp[0]);    
	cusor_moveto(10,3);    
	printf("歌手:%s\n",tmp[1]);    
	cusor_moveto(10,4);    
	printf("专辑:%s\n",tmp[2]);    
	cusor_moveto(10,5);    
	printf("制作:%s\n",tmp[3])return ;
    }
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;    
    pi->next=NULL;      
    if(head==NULL)    
    {        
    head=pi;        
    return head;            
    }      
    else   
     {        
      LRC *pd=head,*pf=head;        
    while(pd->time<pi->time&&pd->next!=NULL)        	
    {           
     	pf=pd;            
    	pd=pd->next;                    
    }
        if(pd->time>pi->time)        
        {            
        if(pd==head)            
        {                
        pi->next=head;                
        head=pi;                
        return head;            
        }
	else            
	{                
	pf->next=pi;                
	pi->next=pd;                
	return head;            
	}        
	}         
	else        
	{            
	pd->next=pi;            
	return head;        
	}                       
	}
	}
LRC *printf_link2(LRC *head,char *buf[],int num)//提取其他行歌词
{    
	LRC tmp;    
	int i=4;       
	for(i=4;i<num;i++)    
	{        
	char *str_lrc=buf[i];
        while(*str_lrc=='[')            
        	str_lrc+=10;
        char *str_time=buf[i];
        while(*str_time=='[')        
        {            
        int m=0,s=0;            			
        sscanf(str_time,"[%d:%d:%*d]",&m,&s);                    
        int time =m*60+s;            
        tmp.time=time;            
        strcpy(tmp.lrc,str_lrc);
        head=insert_link(head,tmp);//将提取出的内容插入到链表
        str_time+=10;        		
         }            
         }    
        return head;
}
#if 0
void printf_link(LRC *head)//打印链表
{    
	if(head==NULL)    
	{        
	printf("link not find\n");        
	return ;    
	}      
	else    
	{        
	LRC *pd=head;        
	while(pd!=NULL)        
	{            
	printf("%d %s\n",pd->time,pd->lrc);            
	pd=pd->next;       
	}    
	}    
}
#endif
void clock_lnk(LRC *head)
{    
	mplayer_play("简单爱.mp3");//启动音乐    
	int i=0;    
	char buf1[128]="";    
	char buf2[128]="";    
	char buf3[128]="";    
	char buf4[128]="";        
	while(1)    
	{
	//打印时间                        
	cusor_moveto(8,6);         
	printf("%02d:%02d ",i/60,i%60);        
	cusor_moveto(19,6);        
	printf(" 04:30");
	//打印皮卡丘字符图片        
	set_fg_color(COLOR_YELLOW);        
	cusor_moveto(40,6);        
	printf("     `;-.          _--\n");        
	cusor_moveto(40,7);        
	printf("       `.`\\_...._/`.-\"`\n");        
	cusor_moveto(40,8);        
	printf("         \\        /      ,\n");        
	cusor_moveto(40,9);        
	printf("         /()   () \\    .' `-._\n");        
	cusor_moveto(40,10);        
	printf("        |)  .    ()\\  /   _.'\n");        
	cusor_moveto(40,11);        
	printf("        \\  -'-     ,; '. <\n");        
	cusor_moveto(40,12);        
	printf("         ;.__     ,;|   > \n");        
	cusor_moveto(40,13);        
	printf("        / ,    / ,  |.-'.-'\n");        
	cusor_moveto(40,14);        
	printf("       (_/    (_/ ,;|.<`\n");        
	cusor_moveto(40,15);         
	printf("         \\    ,     ;-`\n");        
	cusor_moveto(40,16);        
	printf("          >   \\    /\n");        
	cusor_moveto(40,17);        
	printf("         (_,-'`> .'\n");        
	cusor_moveto(40,18);         
	printf("              (_,' \n");         
	set_fg_color(COLOR_BLACK);        
	fflush(stdout);                        
	#if 1  
      
	LRC *ret=search_link(head,i);//插入链表                
	if(ret!=NULL)        
	{
	//歌词滚屏            
	strcpy(buf1,buf2);            
	strcpy(buf2,buf3);            
	strcpy(buf3,buf4);            
	strcpy(buf4,ret->lrc);                 
	cusor_moveto(7,9);            
	printf("%s                   \n", buf1);            
	cusor_moveto(7,10);            
	printf("%s                   \n", buf2);            
	cusor_moveto(7,11);            
	printf("%s                   \n", buf3);            
	cusor_moveto(7,12);            
	set_fg_color(COLOR_RED);            
	printf("%s                   \n", buf4);            
	set_fg_color(COLOR_BLACK);           
        
	}                        
	#endif        
	sleep(1);        
	i++;    
	}    
	return ;
}
LRC *search_link(LRC *head,int i)//链表查找
{    
	if(head==NULL)    
	{        
	printf("link not fine\n");        
	return NULL;    
	}    
	else    
	{        
	LRC *pd=head;        
	while(pd->time!=i && pd->next!=NULL)        
	{            
	pd=pd->next;        
	}
        if (pd->time == i )        
        {            
        return pd;        
        }                
        else        
        {            
        return NULL;        
        }            
        }    
 }
 void free_link(LRC *head)//链表释放 
 {     
 	if(head==NULL)     
 	{         
 	printf("link not find\n");     
 	}     
 	else     
 	{         
 	LRC *pb=head;         
 	while(pb!=NULL)         
 	{             
 	head=pb->next;             
 	free(pb);             
 	pb=head;         
 	}     
 	}     
 	return ;      
 }

fun.h 文件
//头文件,用以函数的声明

#ifndef __FUN_H__
#define __FUN_H__
typedef struct lrc
{    
	int time;    
	char lrc[128];
    	struct lrc *next;    
 }LRC;
extern char *read_file(FILE *fp);
extern void printf_link1(char *buf[]);
extern LRC *insert_link(LRC *head,LRC tmp);
extern LRC *printf_link2(LRC *head,char *buf[],int num);
extern void printf_link(LRC *head);
extern void clock_lnk(LRC *head);
extern LRC *search_link(LRC *head,int i);
extern void free_link(LRC *head);
extern void printf_link3();
#endif

由于我的是在虚拟机内写的,故还需要编译程序
makefile 文件

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

启动mplayer播放器 程序
start_myplayer.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
  ;
}

光标定位的程序及头文件
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 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_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]想~~~ 简!简!单!单! 爱~~~

内容有点多,各位官爷选择查看哦
音乐文件我就不上传了,可根据需要自行去下载~

发布了1 篇原创文章 · 获赞 1 · 访问量 57

猜你喜欢

转载自blog.csdn.net/guoguojiang_/article/details/104851081