C++实现一个简单的歌曲管理系统

课设要求:实现一个简单的歌曲管理系统,允许用户添加、编辑、删除、搜索和展示歌曲信息。系统将使用文本文件存储歌曲数据,以便用户可以在关闭后保持数据持久性。

PS:新手上路,还望各位大佬门们多多指教🤞🤞

1. 功能需求

1.1 数据结构
  • 需要定义一个Song结构,包含以下属性:
    • songNumber(歌曲编号,整数)
    • songName(歌曲名称,字符串)
    • singer(歌手,字符串)
    • language(语言,字符串,可选为中文或英文)
    • releaseDate(发行日期,字符串)
    • downloads(下载量,整数)
1.2 主要功能
  1. 歌曲添加功能

    • 用户可以输入歌曲编号、名称、歌手、语言、发行日期和下载量,系统将该歌曲信息添加到歌曲数据库中。
    • 歌曲编号必须是唯一的,重复编号的添加会被拒绝。
  2. 歌曲编辑功能

    • 用户可以通过输入歌曲编号来查找并编辑已有歌曲的信息,包括名称、歌手、语言、发行日期和下载量。
    • 若歌曲编号不存在,系统需要提示用户。
  3. 歌曲删除功能

    • 用户可以根据歌曲编号删除指定的歌曲。
    • 若歌曲编号不存在,系统需要提示用户。
  4. 歌曲展示功能

    • 系统可以显示当前所有歌曲的信息,包括编号、名称、歌手、语言、发行日期和下载量。
    • 当数据库为空时,系统需要给出提示信息。
  5. 歌曲搜索功能

    • 用户可以通过歌曲名称、编号或歌手进行搜索,系统将返回符合条件的歌曲信息。
  6. 歌曲计数功能

    • 系统可以显示数据库中当前歌曲的总数量。
  7. 插入歌曲功能

    • 用户可以在指定位置插入新歌曲,确保原有歌曲的编号保持正确的顺序。
    • 位置的范围应在当前数据库大小内。
  8. 歌曲排序功能

    • 系统可以根据歌曲编号对数据库中的歌曲进行升序排序。
1.3 持久化存储
  • 所有的歌曲数据需要能够保存到名为songs.txt的文件中,程序启动时加载该文件中的数据。
  • 应用程序在关闭时,会将当前的歌曲数据库保存到该文件中。

2. 用户界面需求

  • 该系统应通过命令行界面与用户交互,提供清晰的文本提示。
  • 用户操作应简单易懂,系统应及时给出操作结果反馈。

3. 安全与错误处理

  • 系统需对子操作进行合理的错误处理,如文件打开失败、输入格式错误等。
  • 对用户输入的数据进行基本的验证,以确保数据的正确性。

头文件:

1.头文件分析

#include <iostream>  
#include <vector>  
#include <algorithm>  
#include <fstream> 
#include<sstream>
#include <string>  

using namespace std;
  • <iostream>: 包含输入输出流的函数
  • <vector>: 提供动态数组的实现,vector<Song> 被用作歌曲数据库的存储。
  • <algorithm>:用于排序以及查找功能。本代码中,使用了 sort 和 find_if
  • <fstream>: 提供文件输入输出的功能,支持在文件中读取和写入。这里的 ifstream 和 ofstream 用于加载和保存歌曲数据。
  • <sstream>: 提供字符串流的支持
  • <string>: 提供字符串类 std::string,用于处理和存储文本数据。

2.数据结构:

struct Song 
{
    int songNumber;//歌曲编号
    string songName;//歌曲名称
    string singer;//歌手
    string language;//语言
    string releaseDate;//发行日期
    int downloads;//下载量
};
  • Song 结构体:定义了一个包含歌曲信息的数据结构,包括歌曲编号、名称、歌手、语言、发行日期和下载量。

3.主功能函数分析

1. 保存数据到文件
void saveToFile() 
{ ofstream file("songs.txt"); ... }
  • 检查文件是否成功打开。
  • 遍历 songDatabase 向量并将每首歌曲的信息写入 songs.txt 文件。
  • 使用简单的空格分隔符分隔各字段。
2. 从文件加载数据
void loadFromFile() 
{ ifstream file("songs.txt"); ... }
  • 检查文件是否存在,若不存在则输出错误信息。
  • 逐行读取数据并构建 Song 对象,使用 push_back 方法添加到 songDatabase
  • 需要注意的是,如果文件格式不正确,可能会导致读取失败。
3. 添加歌曲
void addSong() 
{ Song newSong; ... }
  • 用户输入歌曲信息,并检查编号的唯一性。
  • 使用 getline 方法确保能够读取包含空格的歌曲名称或歌手信息。
  • 将新歌曲添加到 songDatabase 中。
4. 显示所有歌曲
void displaySongs() 
{ ... }
  • 检查 songDatabase 是否为空,若不为空则遍历元素并输出每首歌的信息。
5. 编辑歌曲
void editSong()
 { ... }
  • 用户输入要编辑的歌曲编号,如果找到了相应的歌曲,则允许用户输入新信息并替换旧信息。
  • 使用 find_if 函数寻找歌曲。
6. 删除歌曲
void deleteSong() 
{ ... }

此处删除歌曲时直接调用 erase 方法进行删除。

PS:

如何使用 erase

erase 是被用来删除在 songDatabase 向量中的歌曲。以下是关于如何使用它的一些细节:

  1. 在确定要删除的元素之后,通常先用 remove_if 或其他方法确定要删除的元素,并获得指向新“尾部”的迭代器。
  2. 将 remove_if 返回的迭代器与 vector::end() 传递给 erase 方法,以便实际删除这些元素。
7. 插入歌曲
void insertSong() 
{ ... }
  • 显示现有歌曲列表,要求用户输入插入位置,并进行验证。
  • 调用 addSong 函数用于添加新歌曲。
8. 排序歌曲
void sortSongs() 
{ sort(songDatabase.begin(), songDatabase.end(), [](const Song& s1, const Song& s2) 
{ return s1.songNumber < s2.songNumber; }); }
  • 使用 sort 对 songDatabase 进行排序。

9.统计歌曲数量

void countSongs() 
{
    cout << "总歌曲数量: " << songDatabase.size() << endl;
}
  • countSongs 函数用于计算当前 songDatabase 中存储的歌曲数量,并输出。

10.歌曲搜索功能

void searchSongs()
{
}
  •  searchSongs 函数的主要功能是根据用户的输入来查找歌曲。用户可以选择按歌曲名称、编号或者歌手进行搜索。
  • 输入处理:使用 cin >> ws 来清理输入中的前导空白,确保可以读取字符串。
  • 搜索逻辑:根据用户选择的搜索类型,通过不同的条件判断从 songDatabase 中查找匹配的歌曲。
  • 对于按编号搜索,则找出并显示符合条件的那首歌曲。
  • 对于按名称和按歌手搜索,使用了 vector 来收集所有匹配的结果并输出

源代码

#include <iostream>  
#include <vector>  
#include <algorithm>  
#include <fstream> 
#include<sstream>
#include <string>  
using namespace std;

struct Song 
{
    int songNumber;
    string songName;
    string singer;
    string language;
    string releaseDate;
    int downloads;
};

vector<Song> songDatabase;
//储存
void saveToFile() 
{
    ofstream file("songs.txt");

    if (!file) 
{
     cout << "无法打开文件。" << endl;
        return;
    }

    for (const auto& song : songDatabase) 
{
        file << song.songNumber << " " << song.songName << " " << song.singer << " " << song.language << " " << song.releaseDate << " " << song.downloads << endl;
    }

    cout << "歌曲已保存到文件。" << endl;
}
//加载文件
void loadFromFile()
{
    ifstream file("songs.txt");

    if (!file) {
        cout << "无法打开文件。" << endl;
        return;
    }
    songDatabase.clear();
    int songNumber;
    string songName, singer, language, releaseDate;
    int downloads;

    while (file >> songNumber >> songName >> singer >> language >> releaseDate >> downloads) {
        Song song = { songNumber, songName, singer, language, releaseDate, downloads };
        songDatabase.push_back(song);
    }

    cout << "歌曲已从文件加载。" << endl;
}
//添加
void addSong() 
{
    Song newSong;
    cout << "请输入歌曲编号: ";
    cin >> newSong.songNumber;

    for (const auto& song : songDatabase) {
        if (song.songNumber == newSong.songNumber) {
            cout << "歌曲编号已存在,取消添加。" << endl;
            return;
        }
    }
    cout << "请输入歌曲名称: ";
    cin >> ws;
    getline(cin, newSong.songName);
    cout << "请输入歌手: ";
    cin >> ws;
    getline(cin, newSong.singer);
    cout << "请选择语言 (1. 中文 2. 英文): ";
    int languageChoice;
    cin >> languageChoice;
    newSong.language = (languageChoice == 1) ? "中文" : "英文";
    cout << "请输入发行日期 (YYYY-MM-DD): ";
    cin >> ws;
    getline(cin, newSong.releaseDate);
    cout << "请输入下载量: ";
    cin >> newSong.downloads;
    songDatabase.push_back(newSong);
    cout << "歌曲添加成功。" << endl;
}
//显示歌曲
void displaySongs()
{
    if (songDatabase.empty()) 
{
        cout << "没有任何歌曲。" << endl;
        return;
    }
    cout << "歌曲列表: " << endl;
    for (const auto& song : songDatabase) 
    {
        cout << "歌曲编号: " << song.songNumber << ", 名称: " << song.songName << ", 歌手: " << song.singer << ", 语言: " << song.language << ", 发行日期: " << song.releaseDate << ", 下载量: " << song.downloads << endl;
    }
}

//编辑与修改
void editSong() 
{
    int songNumber;
    cout << "请输入要编辑的歌曲编号: ";
    cin >> songNumber;

    auto song = find_if(songDatabase.begin(), songDatabase.end(), [songNumber](const Song& s) 
{
        return s.songNumber == songNumber;
        });

    if (song != songDatabase.end()) 
{
        cout << "请输入新的歌曲名称: ";
        cin >> song->songName;
        cout << "请输入新的歌手: ";
        cin >> song->singer;
        cout << "请输入新的语言: ";
        cin >> song->language;
        cout << "请输入新的发行日期: ";
        cin >> song->releaseDate;
        cout << "请输入新的下载量: ";
        cin >> song->downloads;
        cout << "歌曲编辑成功。" << endl;
    }
    else 
    {
        cout << "未找到歌曲。" << endl;
    }
}
//删除
void deleteSong() 
{
    int songNumber;
    cout << "请输入要删除的歌曲编号: ";
    cin >> songNumber;
    auto song = find_if(songDatabase.begin(), songDatabase.end(), [songNumber](const Song& s) 
        {
        return s.songNumber == songNumber;
        });

    if (song != songDatabase.end()) 
    {
        songDatabase.erase(song);
        cout << "歌曲删除成功。" << endl;
    }
    else 
    {
        cout << "未找到歌曲。" << endl;
    }
}
//插入添加
void insertSong() 
{
    displaySongs();
    int position;
    cout << "请输入要插入歌曲的位置 (0-" << songDatabase.size() << "): ";
    cin >> position;
    if (position >= 0 && position <= songDatabase.size()) 
    {
        Song newSong;
        cout << "请输入歌曲编号: ";
        cin >> newSong.songNumber;
        for (const auto& song : songDatabase) 
        {
            if (song.songNumber == newSong.songNumber) 
            {
                cout << "歌曲编号已存在,取消插入。" << endl;
                return;
            }
        }
        addSong();
    }
    else 
    {
        cout << "无效的位置,取消插入。" << endl;
    }
}
void sortSongs() 
{
    sort(songDatabase.begin(), songDatabase.end(), [](const Song& s1, const Song& s2) 
        {
        return s1.songNumber < s2.songNumber;
        });

    cout << "歌曲已按歌曲编号排序。" << endl;
}

void countSongs() {
    cout << "总歌曲数量: " << songDatabase.size() << endl;
}

void searchSongs() {
    if (songDatabase.empty()) {
        cout << "歌曲数据库为空,无需搜索。" << endl;
        return; // 如果数据库为空,直接返回  
    }
    int searchType;
    cout << "请选择搜索类型 (1.按歌曲名称 2. 按歌曲编号 3. 按歌手): ";
    cin >> searchType;

    if (searchType == 1) 
    {
        string songName;
        cout << "请输入歌曲名称: ";
        cin >> ws;
        getline(cin, songName);

        auto song = find_if(songDatabase.begin(), songDatabase.end(), [&songName](const Song& s) 
            {
            return s.songName == songName;
            });

        if (song != songDatabase.end()) {
            cout << "找到的歌曲: [编号: " << song->songNumber << "] 名称: " << song->songName
                << ", 歌手: " << song->singer << ", 语言: " << song->language
                << ", 发行日期: " << song->releaseDate << ", 下载量: " << song->downloads << endl;
        }
        else {
            cout << "未找到歌曲。" << endl;
        }
    }
    else if (searchType == 2) {
        int songNumber;
        cout << "请输入歌曲编号: ";
        cin >> songNumber; // 直接使用 cin 读取整数  

        auto song = find_if(songDatabase.begin(), songDatabase.end(), [songNumber](const Song& s) {
            return s.songNumber == songNumber; // 直接比较整数  
            });

        if (song != songDatabase.end()) {
            cout << "找到的歌曲: [编号: " << song->songNumber << "] 名称: " << song->songName
                << ", 歌手: " << song->singer << ", 语言: " << song->language
                << ", 发行日期: " << song->releaseDate << ", 下载量: " << song->downloads << endl;
        }
        else {
            cout << "未找到歌曲。" << endl;
        }
    }
    else if (searchType == 3) {
        string singer;
        cout << "请输入歌手: ";
        cin >> ws;
        getline(cin, singer);

        auto song = find_if(songDatabase.begin(), songDatabase.end(), [&singer](const Song& s) {
            return s.singer == singer;
            });

        if (song != songDatabase.end()) {
            cout << "找到的歌曲: [编号: " << song->songNumber << "] 名称: " << song->songName
                << ", 歌手: " << song->singer << ", 语言: " << song->language
                << ", 发行日期: " << song->releaseDate << ", 下载量: " << song->downloads << endl;
        }
        else {
            cout << "未找到歌曲。" << endl;
        }
    }
    else {
        cout << "无效的搜索类型。" << endl;
    }
}

int main()
{
    int choice;
    while (true)
    {
       
        cout << "1. 从文件加载" << endl;
        cout << "2. 添加歌曲" << endl;
        cout << "3. 删除歌曲" << endl;
        cout << "4. 修改歌曲" << endl;
        cout << "5. 显示歌曲" << endl;
        cout << "6. 插入添加歌曲" << endl;
        cout << "7. 统计歌曲数量" << endl;
        cout << "8. 搜索歌曲" << endl;
        cout << "9. 歌曲排序" << endl;
        cout << "10. 保存到文件" << endl;
        cout << "11. 退出" << endl;
        cout << "请输入选择: ";
        cin >> choice;

        switch (choice)
        {        
        case 1:
            loadFromFile();
            break;
        case 2:
            addSong();
            break;
        case 3:
            deleteSong();
            break;
        case 4:
            editSong();
            break;
        case 5:
            displaySongs();
            break;      
        case 6:
            insertSong();
            break;
        case 7:
            countSongs();
            break;
        case 8:
            searchSongs();
            break;
        case 9:
            sortSongs();
            break;    
        case 10:
            saveToFile();
            break;
        default:
            return 0;

        }
    }
}







  • 10
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个基于单链表的乐库管理系统C++实现方案,供您参考: ```c++ #include <iostream> #include <string> using namespace std; // 定义歌曲信息结构体 struct Song { string name; string artist; string album; int duration; }; // 定义单链表节点结构体 struct SongNode { Song song; SongNode* next; }; // 定义乐库管理系统类 class MusicLibrary { public: // 构造函数 MusicLibrary() { head = NULL; count = 0; } // 析构函数 ~MusicLibrary() { // 释放链表内存 SongNode* p = head; while (p) { SongNode* q = p->next; delete p; p = q; } } // 添加歌曲 void addSong(Song song) { SongNode* node = new SongNode; node->song = song; node->next = head; head = node; count++; } // 删除歌曲 void removeSong(string name) { SongNode* p = head; SongNode* q = NULL; while (p) { if (p->song.name == name) { if (q) { q->next = p->next; } else { head = p->next; } delete p; count--; return; } q = p; p = p->next; } cout << "歌曲不存在" << endl; } // 修改歌曲信息 void updateSong(string name, Song song) { SongNode* p = head; while (p) { if (p->song.name == name) { p->song = song; return; } p = p->next; } cout << "歌曲不存在" << endl; } // 按歌曲名称查找歌曲 Song* findSong(string name) { SongNode* p = head; while (p) { if (p->song.name == name) { return &(p->song); } p = p->next; } return NULL; } // 获取歌曲数量 int getCount() { return count; } private: SongNode* head; int count; }; // 测试代码 int main() { MusicLibrary library; // 添加几首歌曲 Song song1 = {"演员", "薛之谦", "初学者", 230}; Song song2 = {"绅士", "薛之谦", "绅士", 200}; Song song3 = {"认真的雪", "薛之谦", "认真的雪", 260}; library.addSong(song1); library.addSong(song2); library.addSong(song3); cout << "当前歌曲数量:" << library.getCount() << endl; // 查找歌曲 Song* pSong = library.findSong("绅士"); if (pSong) { cout << "歌曲名称:" << pSong->name << endl; cout << "歌手名称:" << pSong->artist << endl; cout << "专辑名称:" << pSong->album << endl; cout << "歌曲时长:" << pSong->duration << endl; } else { cout << "未找到歌曲" << endl; } // 修改歌曲信息 Song song4 = {"绅士", "薛之谦", "绅士(Live版)", 250}; library.updateSong("绅士", song4); pSong = library.findSong("绅士"); if (pSong) { cout << "歌曲名称:" << pSong->name << endl; cout << "歌手名称:" << pSong->artist << endl; cout << "专辑名称:" << pSong->album << endl; cout << "歌曲时长:" << pSong->duration << endl; } else { cout << "未找到歌曲" << endl; } // 删除歌曲 library.removeSong("演员"); cout << "当前歌曲数量:" << library.getCount() << endl; return 0; } ``` 该代码定义了一个MusicLibrary类,包含了添加歌曲、删除歌曲、修改歌曲信息、按歌曲名称查找歌曲等功能。该类内部使用单链表来存储歌曲信息。在测试代码中,我们添加了三首歌曲,然后查找歌曲、修改歌曲信息、删除歌曲,并输出当前歌曲数量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值