//An implement of CSCI-1200 HW1 Spotify Playlists //Author: Jinshan Zhou //Date: 2025/1/16 #include #include #include #include //#include //#include //#include //#include std::string get_text(const std::string &fname) { //load a text file into a string std::ifstream inFile(fname); //check if file exists if (!inFile) { std::cout << "Error: File not found" << std::endl; return ""; } std::string text; std::string line; while (std::getline(inFile, line)) { text += line; text += "\n"; } inFile.close(); return text; } std::vector load_list(const std::string &fname) { //load a text file into a vector of strings std::string text = get_text(fname); std::vector lines; std::size_t start = 0; std::size_t end = 0; while ((end = text.find('\n', start)) != std::string::npos) { lines.push_back(text.substr(start, end - start)); start = end + 1; } if (start < text.size()) { lines.push_back(text.substr(start)); } return lines; } void debug_print(const std::string &msg) { std::cout << "DEBUG: " << msg << std::endl; } bool is_all_digits(const std::string& s) { //check if string is int for (char c : s) { if (!std::isdigit(static_cast(c))) { return false; } } return !s.empty(); } std::vector tokenizer(const std::string &s) { //split string into tokens std::vector tokens; std::string token; for (char c : s) { if (c == ' ') { tokens.push_back(token); token = ""; } else { token += c; } } tokens.push_back(token); return tokens; } bool check_in_list (const std::string &s, const std::vector &list) { //check if string is in list for (std::string item : list) { if (s == item) { return true; } } return false; } void remove_in_list (const std::string &s, std::vector &list) { //remove string from list if (!check_in_list(s, list)) {return;} for (int i = 0; i < list.size(); i++) { if (list[i] == s) { list.erase(list.begin() + i); return; } } } int get_current (std::vector &playlist) { //return the index of the string has word current at the end for (int i = 0; i < playlist.size(); i++) { if (playlist[i].find("current") != std::string::npos) { return i; } } return -1; } std::string build_song (const std::vector &tokens, const int &start, const int &end) { //build string from tokens w/ start and end positions std::string song; for (int i = start; i < end; i++) { song += tokens[i]; if (i != end - 1) { song += " "; } } return song; } void write_list(const std::string &fname, const std::vector &list) { //write list to file std::ofstream outFile(fname); for (std::string line : list) { outFile << line << std::endl; } outFile.close(); } int main(int argc, char *argv[]) { //take 3 arguments if (argc < 3) { std::cout << "Error: Not enough arguments" << std::endl; return 1; } //load arguments std::string playlist_fname = argv[1]; std::string action_list_fname = argv[2]; std::string output_fname = argv[3]; //turn on debug mode is last argument is debug bool debug_mode = false; if (std::string(argv[argc - 1]) == "debug") { debug_mode = true; } if (debug_mode) { debug_print("playlist_fname =" + playlist_fname); debug_print("action_list_fname =" + action_list_fname); debug_print("output_fname =" + output_fname); } //load working files std::vector playlist = load_list(playlist_fname); std::vector action_list = load_list(action_list_fname); //get current playing song id int current_song_id = get_current(playlist); if (debug_mode) { debug_print("current_song_id = " + std::to_string(current_song_id)); } //execute actions for (std::string command : action_list) { if (debug_mode) { debug_print("Command = " + command); } //split command into tokens std::vector tokens = tokenizer(command); if (tokens[0] == "next") { current_song_id = get_current(playlist); //remove "current" tag playlist[current_song_id].erase(playlist[current_song_id].length() - 8); if (current_song_id == playlist.size() - 1) { current_song_id = 0; } else { current_song_id++; } //update current song playlist[current_song_id] += " current"; } if (tokens[0] == "previous") { current_song_id = get_current(playlist); //remove "current" tag playlist[current_song_id].erase(playlist[current_song_id].length() - 8); if (current_song_id == 0) { current_song_id = playlist.size() - 1; } else { current_song_id--; } //update current song playlist[current_song_id] += " current"; } if (tokens[0] == "add") { std::string song; song = build_song(tokens, 1, tokens.size()); playlist.push_back(song); if (debug_mode) { debug_print("Added = " + song); } } if (tokens[0] == "remove") { std::string song; song = build_song(tokens, 1, tokens.size()); remove_in_list(song, playlist); if (debug_mode) { debug_print("Removed = " + song); } } if (tokens[0] == "move") { if (is_all_digits(tokens.back())){ //set target position int dest = std::stoi(tokens.back()); //build song from tokens std::string song; song = build_song(tokens, 1, tokens.size() - 1); //fix song name if it has current tag if (!check_in_list(song, playlist) && !check_in_list(song + " current", playlist)) {continue;} else if (check_in_list(song + " current", playlist)) { song += " current"; } remove_in_list(song, playlist); playlist.insert(playlist.begin() + dest - 1, song); if (debug_mode) { debug_print("Moved " + song + " to " + std::to_string(dest)); } } else { std::cout << "ERROR: Missing move destination" << std::endl; continue; } } } //write back file write_list(output_fname, playlist); if (debug_mode) { debug_print("Playlist Content:"); for (std::string line : playlist) { std::cout << line << std::endl; } } return 0; }