C语言 音乐播放器项目(综合)

news2025/1/18 10:57:24

1.main.c文件

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <unistd.h>//休眠所需的头文件
#include "./pos/console.h"//光标使用所需的头文件
#include "lrc.h"
#include "./mplayer/start_mplayer.h"//播放歌曲的头文件

int main(int argc, char const *argv[])
{
    ontime time = {0,0,0};
    char *text = get_data();
    char *list[50];
    int num = cut_text(text,list);
    showsong(list);
    jay *head = songword(num,list);
    free(text);
    showtime(time);
    showsongtxt(head,NULL);
    mplayer_play("./music/简单爱.mp3");
    jay *pd = head;
    int t = 0;
    while(1)
    {
    int m = t / 60;
    int s = t % 60;
    time.m = m;
    time.s = s;
    showtime(time);
    pd = findspot(head,t);
        if (pd != NULL)
        {
            showsong(list);
            showtime(time);
            jay *h = findstartspot(pd);
            showsongtxt(h,pd);
            if (pd -> n == NULL)
            {
                break;
            }
        }
        sleep(1);
//时间+1
        t++;
    }
    free_link(head);//释放链表
    cusor_show();//显示光标
    return 0;
}

2.lrc.c文件

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "./pos/console.h"
#include "lrc.h"
char *get_data()
{
    FILE *f = fopen("./text/简单爱.lrc", "r");
    if (f == NULL)
    {
        printf("文件打开失败\n");
        return NULL;
    }
    fseek(f, 0, SEEK_END);
    long len = ftell(f);
    rewind(f);
    char *lrc = malloc(len + 1);
    fread(lrc, len, 1, f);
    fclose(f);
    return lrc;
}
int cut_text(char *str, char *list[])
{
    int i = 0;
    list[i] = strtok(str, "\r\n");
    // printf("%s\n",list[i]);
    while (1)
    {
        list[++i] = strtok(NULL, "\r\n");
        if (list[i] == NULL)
        {
            break;
        }
    }
    return i;
}
void showsong(char *list[])
{
    clear_screen();
    cusor_hide();
    char buf[4][50];
    for (int i = 0; i < 4; i++)
    {
        cusor_moveto(40, i + 1); // 光标移到 第0行,第40列
        set_fg_color(COLOR_RED);
        sscanf(list[i], "%*4c%[^]]", buf[i]);
        // printf("%s\n",buf[i]);
    }
}
jay *songword(int num, char *list[])
{
    jay *head = NULL, *newhead = NULL;
    int m, s, ms;
    int timespot[10];
    int timenums = 0;
    char *str;
    for (int i = 4; i < num; i++)
    {
        str = list[i];
        timenums = 0;
        while (*str == '[')
        {
            sscanf(str, "[%2d:%2d.%2d", &m, &s, &ms);
            timespot[timenums] = m * 60 + s;
            timenums++;
            str = str + 10;
        }

        for (int j = 0; j < timenums; j++)
        {
            newhead = malloc(sizeof(jay));
            newhead->time = timespot[j];
            strcpy(newhead->buf_num, str);
            newhead->n = NULL;
            if (head == NULL)
            {
                head = newhead;
                head->l = NULL;
                head->n = NULL;
            }
            else
            {
                jay *myh = head;
                while (newhead->time >= myh->time && myh->n != NULL)
                {
                    myh = myh->n;
                }
                if (myh->time > newhead->time)
                {
                    if (myh == head) // 当前myh为new的下一个节点或者是最后一个节点
                    {
                        newhead->l = NULL;
                        newhead->n = head;
                        head->l = newhead;
                        head = newhead;
                    }
                    else // 当前myh为中间节点
                    {
                        // myh->l = head;
                        // head->n = newhead;
                        // myh = newhead;
                        // newhead->n = newhead;
                        // myh->n = NULL;
                        jay *l = myh->l;
                        l->n = newhead;
                        newhead->l = l;
                        newhead->n = myh;
                        myh->l = newhead;
                    }
                }
                else // 当前myh为第一个节点
                {
                    newhead->l = myh;
                    myh->n = newhead;
                }
            }
        }
    }
    // jay * mmm = head;
    // while(mmm->n != NULL){
    //     printf("%d,%s\n",mmm->time,mmm->buf_num);
    //     mmm = mmm->n;
    // }
    return head;
}
void showtime(ontime time) // 展示时间
{
    char time_num[30];
    sprintf(time_num, "%2d:%2d.%2d", time.m, time.s, time.ms);
    color_pos_printf(time_num, 39, 5, COLOR_GREEN);
}
void showsongtxt(jay *start, jay *pd) // pd为记录的当前节点,start记录的是开始节点--获取歌词
{
    char time_txt[30];
    for (int i = 0; i < 5; i++)
    {
        if (start == pd)
        {
            color_pos_printf(start->buf_num, 30, 6 + i, COLOR_MAGENTA);
        }
        else
        {
            color_pos_printf(start->buf_num, 30, 6 + i, COLOR_YELLOW);
        }
        start = start->n;
    }
}

jay *findspot(jay *lrc, int time) // lrc为头节点,time为时间 --获取节点
{
    while (lrc != NULL)
    {
        if (lrc->time == time)
        {
            return lrc;
        }
        else
        {
            lrc = lrc->n;
        }
    }
    return NULL;
}
jay *findstartspot(jay *lrc) // 寻找开始节点,lrc记录当前节点
{
    // if(lrc->l == NULL)
    // {
    //    return lrc;
    // }
    // else if(lrc->l->l == NULL)
    // {
    //     return lrc->l;
    // }
    // else if(lrc->l->l->l == NULL)
    // {
    //     return lrc->l->l;
    // }
    // else if(lrc->l->l->l->l == NULL)
    // {
    //     return lrc->l->l->l;
    // }
    // else if(lrc->l->l->l->l->l == NULL)
    // {
    //     return lrc->l->l->l->l;
    // }
    if (lrc->l == NULL)
    {
        return lrc;
    }
    // 如果当前节点为第二个节点,那么第一个节点就是开始节点
    else if (lrc->l->l == NULL)
    {
        return lrc->l;
    }
    // 如果当前节点是最后一个节点,那么其上级的上级的上级的上级为开始节点
    else if (lrc->n == NULL)
    {
        return lrc->l->l->l->l;
    }
    // 如果当前节点为倒数第二个节点,那么其上级的上级的上级为开始节点
    else if (lrc->n->n == NULL)
    {
        return lrc->l->l->l;
    }
    // 如果当前节点为3~倒数第三个节点中的某个节点,返回当前节点的上级的上级为开
    else
    {
        return lrc->l->l;
    }
}

void color_pos_printf(char *str, int x, int y, int color)
{
    cusor_moveto(x, y);
    set_fg_color(color);
    printf("%s\n", str);
}
void free_link(jay *head)
{
    while (head != NULL)
    {
        if (head->n != NULL)
        {
            jay *myh = head->n;
            free(head);
            head = myh;
        }
        else
        {
            free(head);
            head = NULL;
        }
    }
}

3.lrc.h文件

#ifndef MY_LRC
#define MY_LRC
typedef struct time
{
    int m;
    int s;
    int ms;
}ontime;

typedef struct jaychou
{
    int time;
    char buf_num[50];
    struct jaychou *l;
    struct jaychou *n;
}jay;
extern char *get_data();
extern int cut_text(char *str,char *list[]);
extern void showsong(char *list[]) ;
extern jay *songword(int num,char *list[]);
extern void color_pos_printf(char *str,int x,int y ,int color);
extern void showtime(ontime time);
extern void showsongtxt(jay *start,jay *pd);
extern jay* findspot(jay *lrc,int time);
extern jay *findstartspot(jay *lrc);
#endif

4.makefile文件

EXEC = main;
OBJ = main.o lrc.o ./pos/console.o ./mplayer/start_mplayer.o;
FLAGS = -wall -g;
CC = gcc;
$(EXEC) :(OBJ)
$(CC) $(OBJ) -o $(EXEC) $(FLAGS);
%.o:%.c %.h
$(CC) -c $< -o $@
clear:
rm $(EXEC) *.o

提示;其他要用的的文件放在资源里面了

示例图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1197148.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

让你的win10/win11系统变得不再卡顿,优雅草伊凡整理-长期更新-如何让windows操作系统不用老是重装在不断的更新中依然保持流畅运行

概述 如题&#xff1a;让你的win10/win11系统变得不再卡顿&#xff0c;优雅草伊凡整理-长期更新-如何让windows操作系统不用老是重装在不断的更新中依然保持流畅运行 本文长期更新&#xff0c;本次更新2023年11月8日&#xff01; 很多时候 我们的win10win11系统不管再怎么关…

基于SSM的软考系统设计实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

Servlet作业小练习

一.题目 利用JavaBean实现用户类&#xff0c;包含姓名、性别、爱好&#xff0c;爱好需要用多选框 实现表单1进行获取数据&#xff0c;表单2显示获取结果。 利用Servlet实现逻辑代码 二.实现效果 三.具体实现 1.User实体类 package com.hjj.pojo;/*** author:嘉佳 Date:20…

【蓝桥杯软件赛 零基础备赛20周】第3周——填空题

报名明年4月蓝桥杯软件赛的同学们&#xff0c;如果你是大一零基础&#xff0c;目前懵懂中&#xff0c;不知该怎么办&#xff0c;可以看看本博客系列&#xff1a;备赛20周合集 20周的完整安排请点击&#xff1a;20周计划 文章目录 00. 2023年第14届参赛数据0. 上一周答疑1. 填空…

环境变量小节

这是写的第二篇环境变量博客&#xff0c;写了一年多了&#xff0c;第一次出现把自己博客删了的情况&#xff0c;不知道为什么明明发表了&#xff0c;然后就把草稿箱和回收站的删了&#xff0c;结果晚上发现没发表&#xff0c;回收站删除是无法找回的&#xff0c;以后还是要慎重…

酷柚易汛ERP-账户管理操作指南

1、应用场景 对账户进行管理&#xff0c;可设置账户当前余额、期初余额和设置是否为默认账户。 2、主要操作 2.1 新增支付账户 打开【资料】-【账款管理】&#xff0c;点击【新增】添加账户类别&#xff0c;输入相关信息并保存&#xff0c;账户编号和名称为必录项。&#x…

VirtualBox网络地址转换(NAT),宿主机无法访问虚拟机的问题

问题&#xff1a;NAT模式下&#xff0c;默认只能从内访问外面&#xff0c;而不能从外部访问里面&#xff0c;所以只能单向ping通&#xff0c;虚拟机的ip只是内部ip。 PS&#xff1a;桥接则是与主机公用网卡&#xff0c;有独立的外部ip。 解决&#xff1a;NAT模式可以通过配置 …

最简WebClient 同步、异步调用示例

目录 一&#xff0c;序言二&#xff0c;简单示例1. 引入依赖2. 日志配置3. 调用代码4. 运行结果 三&#xff0c;完整代码 一&#xff0c;序言 WebClient是Spring WebFlux模块提供的一个非阻塞的基于响应式编程的进行Http请求的客户端工具&#xff0c;从Spring5.0开始WebClient…

【JavaEE初阶】 TCP协议详细解析

文章目录 &#x1f332;TCP协议的概念&#x1f6a9;TCP协议段格式&#x1f6a9;TCP的特性 &#x1f333;TCP原理&#x1f6a9;确认应答机制&#xff08;安全机制&#xff09;&#x1f6a9;超时重传机制&#xff08;安全机制&#xff09;&#x1f6a9;三次握手四次挥手&#xff…

【蓝桥杯选拔赛真题65】Scratch水下探险 少儿编程scratch图形化编程 蓝桥杯创意编程选拔赛真题解析

目录 scratch水下探险 一、题目要求 编程实现 二、案例分析 1、角色分析

概念解析 | Richardson-Lucy去卷积算法

注1:本文系“概念解析”系列之一,致力于简洁清晰地解释、辨析复杂而专业的概念。本次辨析的概念是:Richardson-Lucy去模糊算法 Richardson-Lucy去模糊算法:重现图像的真实面目 Blind deconvolution by means of the Richardson–Lucy algorithm 背景介绍 在图像处理中,图像获取…

jQuery实现二级菜单

jQuery怎么实现二级菜单呢&#xff1f;让我为大家演示一个例子&#xff01; 上代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title></title><style>* {margin: 0;padding: …

Spring源码系列-Spring事务

声明式事务 spring事务&#xff0c;是通过数据库连接来实现的&#xff0c;当前线程中保存了一个map&#xff0c;key是数据原&#xff0c;value是数据库连接 我们说的同一个事务&#xff0c;其实指的是同一个数据库连接&#xff0c;只有拥有同一个数据库连接才能同时提交和回滚。…

C语言实现编写一个函数,输入n为偶数时,调用函数求1/2+1/4+...+1/n,当输入n为奇数时,调用函数1/1+1/3+...+1/n

完整代码&#xff1a; /*编写一个函数&#xff0c;输入n为偶数时&#xff0c;调用函数求1/21/4...1/n,当输入n为奇数时&#xff0c; 调用函数1/11/3...1/n */ #include<stdio.h>//n为偶数 double Odd(int n){double sum0;//i为2&#xff0c;4&#xff0c;6....for (int …

mybatis的简单教程

整体就是mysql里存了一张表&#xff0c;然后在java程序里用mybatis把数据读出来的一个简单示例。 库 blog里有一张表 article 整个项目就是增加了这3个文件 首先是mybatis-config.xml文件 <?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE c…

【Python】20大报告生成词云

这个我其实写过一篇类似的博客&#xff0c;但是那个的文件对象是.csv&#xff0c;对应到.docx文件的话&#xff0c;就不太适用了。如下&#xff1a; Python生成词云-CSDN博客 代码&#xff1a; import jieba import os import wordcloud import numpy as np from PIL import…

多测师肖sir_高级金牌讲师_ui自动化po框架版本01

ui自动化po框架 一、po框架 1、基本介绍 &#xff08;1&#xff09;po模式是page object model的缩写&#xff08;简称&#xff1a;po或pom&#xff09; &#xff08;2&#xff09; po模式的核心思想&#xff1a;分层&#xff0c;实现耦合 实现&#xff1a;业务流程与页面元素操…

n-gram语言模型——文本生成源码

n-gram语言模型——文本生成源码 n-gram模型的基本原理 文本生成的步骤 1. 准备和分词 2. 构建n-gram模型 3. 平滑技术的应用 4. 生成文本 源码 在自然语言处理的领域中&#xff0c;n-gram语言模型是一种基础而强大的工具。它通过考虑词汇的序列来预测文本内容&#xff…

阿里大佬:DDD中Interface层、Application层的设计规范

说在前面 在40岁老架构师 尼恩的读者交流群(50)中&#xff0c;最近有小伙伴拿到了一线互联网企业如阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格&#xff0c;遇到很多很重要的面试题&#xff1a; 谈谈你的DDD落地经验&#xff1f; 谈谈你对DDD的理解&#xff1f…

redis主从复制+哨兵

1.主从复制 redis配置文件redis.conf master机器&#xff1a;IP 192.168.1.5 &#xff0c;端口 6379 设置配置参数 daemonize yes #bind 127.0.0.1 -::1 protected-mode no port 6379 dbfilename "dump.rdb" dir "/root/redis/my_redis_conf/dumpdir" l…