0x00. 前言
更換了編輯器為markdown,來碼一個以前的編程作業,KTV點歌系統.
0x01. 選題
模擬KTV點歌系統。用戶可按歌名查找某首歌曲或按歌手名查找其所有歌曲,點歌后顯示所點歌曲歌詞。管理員可添加和刪除歌曲,每個歌曲的歌詞用一個單獨的文件存儲。
0x02. 軟件的功能要求
- 查詢歌手的歌曲功能、
- 查詢歌曲的歌詞功能、
- 登錄管理員功能、
- 增添歌曲及其歌詞功能、
- 刪除歌曲(文件)功能、
- 修改管理員密碼功能 等
0x03. 作為驗收的依據,選取的測試用例及對應的驗收數據
把歌手以其姓名文件命名,文件內每行都是他(她)的一首歌曲,文件夾名singer;歌詞以其歌曲文件命名,文件內是歌詞內容,文件夾名song。文件下載地址
- 查詢/刪除歌曲:可選擇下圖1的所有內容。
- 查詢歌手:可選擇下圖2的所有內容。
- 登錄管理員:登錄密碼是初始化的 'admin123'。
- 增添歌曲:歌曲名直接輸入、歌詞內容直接復制粘貼(末尾行要輸入quit然后回車)
0x04. 各模塊的描述
函數總體上是很簡單的 ,除了登錄函數login返回一個int整數表示不同的登錄狀態,其他的函數都是無傳參、無返回值的。
main函數的第一個while循環,根據輸入數字選擇功能,以實現下面三個功能:查詢歌曲歌詞(select_song函數)、查詢歌手歌曲(select_singer函數)、登錄功能(login函數);如果沒輸入1 2 3就退出程序。值得注意的是登錄函數返回值傳給state變量保存,登陸成功后state == 1。
main函數第二個while循環便是依據state變量判斷是否已登錄,如果沒有登錄就直接結束了程序,state為1就作為管理員運行第二個while循環。這個循環和上一個循環的實現異曲同工,完全是根據輸入選擇不同功能,輸入非1 2 3就結束循環退出程序。
0x05. 軟件結構圖
0x06. 使用說明
基於GCC編譯器或VC6編譯器。
文本文件是UTF-8編碼,如果用cmd直接執行會顯示亂碼,我用的是cmder前端命令行工具,它支持UTF-8編碼,可以正常顯示。
文件夾結構:
0x07. 測試結果
1. 點歌結果
2. 查詢歌手
3. 登錄管理員
可以清楚地看到,登錄初始密碼為admin123,登陸后會進入管理員界面,可以選擇添加歌曲、刪除歌曲、更改密碼等功能。
3.1 添加歌曲
值得注意的是,上面歌詞最后一行輸入quit回車來確認歌詞提示輸入完畢,結束輸入歌詞過程。此時打開歌曲目錄能找到新添加的文件:黑貓警長.txt:
3.2 刪除剛剛添加的歌曲
3.3 管理員更改登錄密碼
0x08. 代碼
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
char admin_password[16] = "admin123";
void select_song();
void select_singer();
int login();
void del_song();
void add_song();
void change_password();
int main()
{
int num=0,state=0;
// char choice;
char namebuf[32]={0},singerbuf[32]={0};
printf("大爺來玩啊??boo~\n");
while(1)
{
printf("***********************************************************\n");
printf("**點歌請輸入1 查看歌手信息請輸入2 輸入3登錄管理員 否則退出*\n");
printf("***********************************************************\n");
scanf("%d",&num);
if(num == 1)
select_song();
else if(num == 2)
select_singer();
else if(num == 3)
{
state = login();
if(state == 1) //如果登錄成功馬上跳出次循環,開啟下一層循環,選擇管理員操作
break;
}
else //輸入數據非1 2 3就跳出循環 結束程序
break;
}
//普通用戶無法執行次循環
while(state == 1){
printf("######################################################\n");
printf("##刪除歌曲選擇1 添加歌曲選擇2 更改密碼選擇3 否則退出##\n");
printf("######################################################\n");
scanf("%d",&num);
if(num == 1)
del_song();
else if(num == 2)
add_song();
else if(num == 3)
change_password();
else
break;
}
printf("\n歡迎下次再來!\n");
return 0;
}
void select_song()
{
FILE *fp;
char song_name[20]={0};
char buff[200] = {0};
char temp[20] = {0};
int len;
printf("請輸入歌曲名:");
scanf("%s",song_name);
/*給該歌曲名加上文件路徑(song文件夾里的歌名.txt文件)*/
strcpy(temp,song_name);
strcpy(song_name,"song//");
strcpy(&song_name[6],temp);
len=strlen(song_name);
strcpy(&song_name[len],".txt");
/*從該路徑打開以歌曲命名的文件,提取歌詞*/
if((fp=fopen(song_name,"r"))==NULL)
{
printf("不存在這首歌曲!\n");
}
else
{
printf("#############################################\n");
printf(" 正在播放:%s\n",temp);
printf("歌詞:\n");
while(fgets(buff,200,fp)!=NULL)
printf("%s",buff);
printf("\n 播放完畢:%s",temp);
printf("\n#############################################\n");
fclose(fp);
}
}
void select_singer()
{
FILE *fp1;
char singer_name[20]={0};
char temp[20]={0};
char buff[100] = {0};
int len;
printf("請輸入歌手名:");
scanf("%s",singer_name);
/*給該歌手加上文件路徑*/
strcpy(temp,singer_name);
strcpy(singer_name,"singer//");
strcpy(&singer_name[8],temp);//strlen("singer//")=8
len=strlen(singer_name);
strcpy(&singer_name[len],".txt");
/*讀取歌手文件中保存的該歌手的所有歌曲*/
if((fp1=fopen(singer_name,"r"))==NULL)
{
printf("不存在歌手!");
}
else
{
printf("歌手全部歌曲如下:\n");
printf("|--------------------------|\n");
while(fgets(buff,100,fp1)!=NULL)
{
printf("%s",buff);
}
fclose(fp1);
printf("\n|--------------------------|\n");
}
}
int login(){
int state=0;
char buf[16]={0};
printf("輸入密碼: ");
scanf("%s",buf);
if(strcmp(admin_password,buf)==0){
printf("登陸成功!\n");
state=1;
}
else
printf("登錄失敗,以普通用戶身份訪問系統。\n");
return state;
}
void del_song()
{
char song_name[32]={0},temp[64]={0};
int len = 0;
printf("輸入要刪除的歌曲名字:\n");
scanf("%s",song_name); //song_name = "xxx"
strcpy(temp,song_name); //先把歌曲名賦值給temp
strcpy(song_name,"song//");//song_name = "song//" song文件夾下存放歌曲文件
strcpy(&song_name[6],temp); //song_name = "song//xxx"
len=strlen(song_name);
strcpy(&song_name[len],".txt"); //song_name = "song//xxx.txt"
if (!remove(song_name))
printf("刪除歌曲 %s 成功!\n",song_name); //刪除成功
else
perror("刪除歌曲失敗!");//打印錯誤信息
}
void add_song()
{
char song_name[32]={0},temp[64]={0},buf[1024]={0};
int len = 0;
FILE *fp;
printf("輸入要新建的歌曲名字:\n");
scanf("%s",song_name); //song_name = "xxx"
strcpy(temp,song_name); //先把歌曲名賦值給temp
strcpy(song_name,"song//");//song_name = "song//" song文件夾下存放歌曲文件
strcpy(&song_name[6],temp);//song_name = "song//xxx"
len=strlen(song_name);
strcpy(&song_name[len],".txt");//song_name = "song//xxx.txt"
fp = fopen(song_name,"w");
if(fp == NULL)
perror("歌曲添加失敗");
else{ // 新建歌曲文件成功
printf("現在輸入歌詞內容,單行輸入quit結束輸入:\n");
printf("---------------------------------------\n");
scanf("%s",buf); //一次接受一行歌詞
while( strcmp(buf,"quit") != 0 ){ //比較此行內容是否為quit,如果是就結束循環,關閉文件
buf[strlen(buf)]='\n'; //scanf字符串不接受換行符,為了美觀人為在緩沖區歌詞末尾加上換行符
fputs(buf,fp); //寫入文件
memset(buf,0,sizeof(buf));
scanf("%s",buf); //一次接受一行歌詞
}
printf("---------------------------------------\n輸入完畢!\n");
fclose(fp);
}
}
void change_password()
{
char buf[32]={0};
printf("輸入新的密碼: ");
scanf("%s",buf);
memset(admin_password,0,sizeof(admin_password));
strcpy(admin_password,buf);
printf("更換成功!新密碼:'%s'\n",admin_password);
}