// // C++の練習用。検索機能が作りかけ。 // #include #include #include using namespace std; class songdata{ public: char title[50]; char vocal[40]; char words[30]; char compo[30]; }; vector songobject; int menu() { int ret; //戻り値(RETurn) cout << "\n\n--------[メニュー]--------\n"; cout << "1: 楽曲情報の入力\n"; cout << "2: 楽曲情報の参照,変更,削除\n"; cout << "3: 検索\n"; cout << "4: ロード\n"; cout << "5: セーブ\n"; cout << "6: えんい〜\n"; cout << "0: 日本語入力ってどうやるの?\n..."; cin >> ret; return ret; } // タイトルでソート int sortob(const void *x, const void *y) { return ( strcmp(((songdata *)x)->title, ((songdata *)y)->title) ); } // 入力や変更 int enter(int target=-1) // 新規なら-1がターゲット { songdata temp; // いわゆるバッファ cout << "\n\n--------[曲情報の入力,変更]--------\n"; cout << "タイトルは?(空改行で戻る)\n"; gets(temp.title); if(!strcmp(temp.title, "")) return 0; cout << "歌は?\n"; gets(temp.vocal); if(!strcmp(temp.vocal, "")) strcpy(temp.vocal, "NoInfo"); cout << "作詞は?\n"; gets(temp.words); if(!strcmp(temp.words, "")) strcpy(temp.words, "NoInfo"); cout << "作曲者は?\n"; gets(temp.compo); if(!strcmp(temp.compo, "")) strcpy(temp.compo, "NoInfo"); cout << "お疲れ。\n"; if(target==-1) songobject.push_back(temp); else songobject[target] = temp; qsort(songobject.begin(), songobject.size(), sizeof(songdata), sortob); // 曲名順にソート return 0; } // 削除 void del(int target) { bool cancel; cout << "\n\n--------[あぼーん]--------\n"; cout << "\"" << songobject[target].title << "\""; cout << "を削除してもいいのか? (0): はい / (1): いいえ\n..."; cin >> cancel; if(!cancel){ vector::iterator itr=songobject.begin(); itr += target; songobject.erase(itr); cout << "削除しました。\n"; } else cout << "キャンセルされました。\n"; } // オブジェクトを見る int showall(int objectnumber) { int req; if((objectnumber<0)||(objectnumber>=(signed int)songobject.size())){ cout << "不正な値です\n"; return 1; } for(;;){ cout << "\n--------[楽曲詳細]--------\n"; cout << " Title :" << songobject[objectnumber].title << "\n"; cout << " Vocal :" << songobject[objectnumber].vocal << "\n"; cout << " Words :" << songobject[objectnumber].words << "\n"; cout << " Conpose:" << songobject[objectnumber].compo << "\n\n"; cout << "(0): メニューへ / (1): 一覧へ / (2): 曲情報の変更 / (3): あぼーん\n..."; cin >> req; switch(req){ case 0: return 0; case 1: return 1; case 2: enter(objectnumber); break; case 3: del(objectnumber); return 1; default: cout << "え!?\n"; } } } // 一覧を参照 int show() { if(!(songobject.size())){ cout << "曲情報が一つもありません\n"; return 0;} for(;;){ cout << "\n\n--------[曲情報一覧]--------\n"; if(!(songobject.size())){ cout << "今消したのが最後の一曲・・・\n"; return 0;} for(;;){ // ここで一覧を実装 int i=0, req; cout << "現在の登録曲数:" << songobject.size() << "曲\n"; if(i+11<(signed int)songobject.size()){ // あと11以上のオブジェクトあり for(int j=0; j<10; j++){ cout << (i+1) << ": " << songobject[i].title <<"\n"; i++; } cout << "(0): 次へ / (no.): 曲詳細\n..."; cin >> req; if(req){ if(!showall(req-1)) return 0; // 0ならメニューへ else break; // 1なら一覧を最初から } return 0; } else if(i+10<(signed int)songobject.size()){ // あと10のオブジェクトがある for(int j=0; j<10; j++){ cout << (i+1) << ": " << songobject[i].title << "\n"; i++; } cout << "(0): メニューへ / (no.): 曲詳細\n..."; cin >> req; if(req){ if(!showall(req-1)) return 0; // 0ならメニューへ else break; // 1なら一覧を最初から } return 0; } else{ // 残りは10以下 for(; i<(signed int)songobject.size();){ cout << (i+1) << ": " << songobject[i].title << "\n"; i++; } cout << "(0): メニューへ / (no.): 曲詳細\n..."; cin >> req; if(req){ if(!showall(req-1)) return 0; // そういうことでつ else break; } return 0; } } // 二つ目のforの終わり。紛らわしくてすまん。 } } // 検索 int search() { int opt; char keyword[50]; cout << "\n\n--------[検索]--------\n"; cout << "(0): タイトル検索 / (1): 戻る\n..."; cin >> opt; if(opt==1){ return 0;} if(!opt){ songdata *result; cout << "タイトルを入力..."; gets(keyword); if((result=(songdata *)bsearch(keyword, songobject.begin(), songobject.size(), sizeof(songdata), sortob)) == NULL){ cout << "........見つかりません\n"; return 0; } cout << "........見つかりました。\n\n"; cout << "--------[Result]--------\n\n"; cout << " Title :" << result->title << "\n"; cout << " Vocal :" << result->vocal << "\n"; cout << " Words :" << result->words << "\n"; cout << " Conpose:" << result->compo << "\n"; } return 0; } // ディスクに書き出す。 void save() { bool cancel; unsigned int size; cout << "\n\n--------[セーブ]--------\n"; cout << "すでにファイルが存在する場合上書きされます。\n"; cout << "よろしいですか? (0): ディスクにセーブ / (1): キャンセル\n..."; cin >> cancel; if(!cancel){ ofstream fout("database.song", ios::binary); // 開く if(!fout){ cout << "ファイルを開けません\n"; exit(1);} // エラー検査 // songobjectの数を書き込む size = songobject.size(); fout.write((const char *)&size, sizeof(unsigned int)); if(!(fout.good())){ cout << "書き込みエラー\n"; exit(1);} // エラー検査 //曲情報の書き込み fout.write((const char *)songobject.begin(), sizeof(songdata)*size); if(!(fout.good())){ cout << "書き込みエラー\n"; exit(1);} // エラー検査 // 閉じる fout.close(); // まさか失敗しないだろう(w cout << "セーブに成功しました。メニューへ戻ります。\n"; } else cout << "キャンセルされました。\n"; } // ディスクからロード void load() { bool cancel; unsigned int size; cout << "\n\n--------[ロード]--------\n"; cout << "ディスクからロードします。よろしいですか?\n"; cout << "(0): ディスクからロード / (1): キャンセル\n..."; cin >> cancel; if(!cancel){ ifstream fin("database.song", ios::binary); // 開く if(!fin){ cout << "ファイルが存在しないか、開けませんでした\n"; exit(1);} // songobjectの個数を読む fin.read((char *)&size, sizeof(unsigned int)); if(!(fin.good())){ cout << "読み込みエラー\n"; exit(1);} // エラー検査 // サイズを広げておく songobject.reserve(size+1); // 個数分だけオブジェクトを読む fin.read((char *)songobject.begin(), sizeof(songdata)*size); if(!(fin.good())){ cout << "読み込みエラー\n"; exit(1);} // エラー検査 fin.close(); // 多分大丈夫 songobject.resize(size); cout << "ロードしました。メニューへ戻ります。\n"; } else cout << "キャンセルされました。\n"; } int main() { int choice; load(); for(;;){ choice = menu(); // メニューへ switch(choice){ case 0: cout << "[Alt]+[全角+半角]で多分おk\n"; break; case 1: enter(); break; // 新規入力 case 2: show(); break; case 3: search(); break; case 4: load(); break; case 5: save(); break; default: return 0; } } }