用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
- 收藏
- 分享
- 文章举报
- 【Unity】制作简单的登录界面和实现线框高亮
- 简单c语言练习:学生数据库的制作
- PHP制作简单仿路由器登录界面
- 使用tkinter制作一个简单的标签文本框输入界面,并打包成exe文件
- 将自己的工作环境全面移植到C++---最后一道工序:能用MFC制作简单的图形界面
- 利用Java制作一个简单的QQ登录界面
- 请帮忙:WPF学习——制作一个简单的录入界面(3):界面存在的问题
- Android 超简单音乐播放器(五) 发送歌曲信息到详情界面
- 『C # 开发』技能 Get√ ——制作CMD界面的简单GIF图片
- 简单医疗系统设计(一)登录界面的制作
- 利用hibernate与struts框架制作简单注册界面
- JSP制作简单登录界面实例
- Android如何制作一个简单的登陆界面
- 使用HTML制作简单的小米界面(部分)
- 【C语言】超级简单的字符界面
- 简单C语言实现由1-N组成一个N位各位不重复的数字,该数字前M个数字组成的数可以被M整除
- Qt4学习(1)——制作简单的计算器界面
- 留念 C语言第一课简单的计算器制作
- 使用HTML+CSS+JS制作简单的网页菜单界面
- NGUI制作简单聊天界面