C数据结构 模拟播放器

本文介绍了一个基于链表实现的简易音乐播放器程序。该程序使用C语言编写,包括歌曲信息管理、播放控制等功能。文章详细展示了如何通过链表进行歌曲的增删改查,并实现了顺序播放、倒序播放、循环播放等播放功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


// MusicPlayer.cpp :定义控制台应用程序的入口点。
//作者Tst

#include"stdafx.h"
#include"malloc.h"
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<windows.h>
#include<locale.h>
#include<time.h>

typedef struct MusicPlayer{
	char Song[20];    //存取歌曲名
	char Singer[10];  //存取歌曲作者
	struct MusicPlayer *prior;   //前驱
	struct MusicPlayer *crunt;   //指向当前节点
	struct MusicPlayer *next;    //后驱
}Song, *LinkList;

LinkList gp;        //全局变量,数据交接
LinkList Temp_G_p;  //用于存储播放操作后的指针指向(crunt的位置)
char Song_Name[20]; //获取控制台输入的歌曲名(字符)
char author[20];    //获取控制台输入的作者名(字符)
int Count = 1;        //计数器

/*创建歌单*/
LinkList CreatMusicmenu(){
	Temp_G_p = (LinkList)malloc(sizeof(Song));
	LinkList head, tail, r;
	int i = 1;
	head = (LinkList)malloc(sizeof(Song));
	head->next = NULL;
	tail = head;
	r = (LinkList)malloc(sizeof(Song));
	printf("歌曲名:");
	getchar();
	strncpy_s(r->Song, gets_s(Song_Name), 20);  //将Song_Name的字符传递给Song
	printf("作者:");
	scanf_s("%s", author, 20);
	strncpy_s(r->Singer, author, 20);  //将author的字符传递给Singer
	tail->crunt = r;  //赋值crunt,使其指向当前

	//printf("这是tail:%s\n",tail->crunt->Song);
	Temp_G_p->crunt = tail->crunt;  //在tail改变之前初始化Temp_G_p->crunt
	//printf("这是Temp_G_p->crunt:%s\n",Temp_G_p->crunt->Song);

	tail->next = r;
	r->prior = tail;
	tail = tail->next;
	tail->next = head;
	head->prior = tail;
	printf("歌单已创建!\n");
	return head;
}

/*遍历*/
void Treval(LinkList H){
	LinkList p = H;
	int i = Count;//计数器
	int j = Count;//计数器
	if (p->next == p || p->prior == p){ //判断为空的条件
		printf("该歌单为空!\n");
	}
	else{
		printf("\t\t\t 歌单列表\n");
		printf("\t\t-----------------------------\n");
		while (p->next != H){
			i--;
			printf("\t\t%d.《%s》 - %s\n", j - i, p->next->Song, p->next->Singer);// j-i 用于自动更新歌曲的序号
			p = p->next;
		}
		printf("\t\t-----------------------------\n");
	}
}

/*新增歌曲*/
void Insert(LinkList H){
	LinkList p = H, r;
	r = (LinkList)malloc(sizeof(Song));
	printf("歌曲名:");
	getchar();
	strncpy_s(r->Song, gets_s(Song_Name), 20);
	printf("作者:");
	/*注释部分引用后会输出乱码,尚未解决,换了输入的方法*/
	//getchar();
	//strncpy_s(r->Singer,gets_s(author), 5);
	scanf_s("%s", author, 20);
	strncpy_s(r->Singer, author, 20);
	r->prior = p->prior;
	r->next = p;
	p->prior->next = r;
	p->prior = r;
	Count++;
}

/*修改歌曲信息*/
void Update(LinkList H){
	LinkList p = H;
	char chose;//计数器
	int position;//定位变量
	if (p->next == p || p->prior == p){
		printf("该歌单为空!\n");
	}
	else{
		printf("确定修改?确认输入Y,退出输入N: ");
		getchar();
		scanf_s("%c", &chose);
		switch (chose){
		case'Y':
			printf("你要修改第几首歌曲信息?请输入序号:");
			scanf_s("%d", &position);
			for (int i = 1; i <= position; i++){
				if (NULL == p->next){
					break;
				}
				p = p->next;
			}
			printf("歌曲名:");
			getchar();
			strncpy_s(p->Song, gets_s(Song_Name), 20);
			printf("作者:");
			scanf_s("%s", author, 20);
			strncpy_s(p->Singer, author, 20);
			printf("正在修改,请稍候");
			for (int i = 0; i < 3; i++){
				Sleep(850);
				printf(".");
			}
			printf("\n");
			//Judgment();//此处应该有一个判断是否修改成功的语句
			printf("信息修改成功!\n");
			break;
		case'N':
			break;
		default:
			printf("指令错误,退出修改!\n");
			break;
		}
	}
}

/*移除歌曲*/
void Del(LinkList H){
	LinkList p = H;
	int position;
	if (p->next == p || p->prior == p){
		printf("该歌单为空!\n");
	}
	else{
		printf("你想删除第几首歌曲?请输入序号:");
		scanf_s("%d", &position);
		printf("正在移除,请稍候");
		for (int i = 0; i < 3; i++){
			Sleep(850);
			printf(".");
		}
		printf("\n");
		for (int i = 1; i <= position; i++){
			if (NULL == p->next){
				break;
			}
			p = p->next;
		}
		p->prior->next = p->next;
		p->next->prior = p->prior;
		free(p);
		p = NULL;
		printf("移除成功!\n");
		Count--;
	}
}

/*顺序播放*/
void SequetialPlay(LinkList H){//正向遍历链表
	LinkList p = H;
	if (p->next == p || p->prior == p){
		printf("该歌单为空!\n");
	}
	else{
		while (p->next != H){
			printf("%s\n", p->next->Song);
			p = p->next;
			Sleep(2000);//线程沉睡
		}
	}
	Temp_G_p->crunt = p->crunt;
}

/*倒序播放*/
void ReversePlay(LinkList H){//逆向遍历链表
	LinkList p = H;
	if (p->next == p || p->prior == p){
		printf("该歌单为空!\n");
	}
	else{
		while (p->prior != H){
			printf("%s\n", p->prior->Song);
			p = p->prior;
			Sleep(2000);
		}
	}
}

/*循环播放*/
void CycPlay(LinkList H){
	LinkList p = H;
	if (p->next == p || p->prior == p){
		printf("该歌单为空!\n");
	}
	else{
		int i = 0, j = 0, n;
		printf("你希望循环播放几次:");
		scanf_s("%d", &n);
		printf("%d\n", Count);
		while (i < n)
		{
			while (j<Count)
			{
				printf("%s\n", Temp_G_p->crunt->Song);
				Temp_G_p->crunt = Temp_G_p->crunt->next;
				if (Temp_G_p->crunt == H){
					Temp_G_p->crunt = Temp_G_p->crunt->next;
				}
				//Sleep(900);//线程沉睡
				j++;
			}
			j = 0;//重置j
			i++;
		}
	}
}

/*下一首*/
void nextPlay(LinkList H){//逐个正向遍历
	LinkList p = H;
	if (p->next == p || p->prior == p){
		printf("此歌单为空!!\n");
	}
	else{
		printf("%s\n", Temp_G_p->crunt->Song);
		Temp_G_p->crunt = Temp_G_p->crunt->next;//指向当前的指针后移

		//跳过头节点,因为歌单链表的头不存储值,当前指针crunt输出NULL转为乱码。
		if (Temp_G_p->crunt == H){
			Temp_G_p->crunt = Temp_G_p->crunt->next;
		}
	}
}

/*上一首*/
void prePlay(LinkList H){//逐个逆向遍历
	LinkList p = H;
	if (p->next == p || p->prior == p){
		printf("此歌单为空!!\n");
	}
	else{
		printf("%s\n", Temp_G_p->crunt->Song);
		Temp_G_p->crunt = Temp_G_p->crunt->prior;//指向当前的指针前移

		//跳过头节点,因为歌单链表的头不存储值,当前指针crunt输出NULL转为乱码。
		if (Temp_G_p->crunt == H){
			Temp_G_p->crunt = Temp_G_p->crunt->prior;
		}
	}
}

/*switch模块控制*/
void Operate();//函数索引标签
void Operate1(){
	char flag;
	printf("\t\t     Menu\n");
	printf("\t\t-----------------\n");
	printf("\t\t1 -顺序播放\n");
	printf("\t\t2 -倒序播放\n");
	printf("\t\t3 -下一曲\n");
	printf("\t\t4 -上一曲\n");
	printf("\t\t5 -循环播放\n");
	printf("\t\t0 -返回上一级\n");
	printf("\t\t-----------------\n");
	printf("\t\t\t\t\t\t  输入指令:");
	while (true){
		scanf_s("%d", &flag);
		switch (flag){
		case1:
			SequetialPlay(gp);
			printf("\n\t\t\t\t\t\t  输入指令:");
			break;
		case2:
			ReversePlay(gp);
			printf("\n\t\t\t\t\t\t  输入指令:");
			break;
		case3:
			nextPlay(gp);
			printf("\n\t\t\t\t\t\t  输入指令:");
			break;
		case4:
			prePlay(gp);
			printf("\n\t\t\t\t\t\t  输入指令:");
			break;
		case5:
			CycPlay(gp);
			printf("\n\t\t\t\t\t\t  输入指令:");
			break;
		case0:
			Operate();//返回上一级
			break;
		}
	}
}
void Operate(){
	int flag;
	printf("\t\t\t\t\t\t  MuscicPlayer\n");
	printf("\t\t-----------------\n");
	printf("\t\t1 -创建歌单\n");
	printf("\t\t2 -浏览歌单\n");
	printf("\t\t3 -新增歌曲\n");
	printf("\t\t4 -修改歌曲信息\n");
	printf("\t\t5 -移除歌曲\n");
	printf("\t\t6 -进入播放界面\n");
	printf("\t\t0 -退出播放器\n");
	printf("\t\t-----------------\n");
	while (true)
	{
		printf("\t\t\t\t\t\t  输入指令:");
		scanf_s("%d", &flag);
		switch (flag){
		case1:
			gp = CreatMusicmenu();
			break;
		case2:
			Treval(gp);
			break;
		case3:
			Insert(gp);
			break;
		case4:
			Update(gp);
			break;
		case5:
			Del(gp);
			break;
		case6:
			Operate1();//进入播放界面
			break;
			//case10://检验Count(不显示在指令表)
			// printf("%d", Count);
			// break;
		case0:
			printf("即将退出,请稍候");
			for (int i = 0; i < 3; i++){
				Sleep(750);
				printf(".");
			}
			printf("\n");
			return;
			break;
		default:
			//处理输入非指令的异常
			printf("指令表不包含指令\n");
			break;
		}
	}
}

/*主函数入口*/
void main(){
	Operate();
	system("pause");//控制闪屏
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值