第44章 住所録を作ろう その7


今回は、データのある項目のみ表示する機能を追加します。 たとえば、氏名のみを表示するという機能を付け加えます。

これは、データ全体をざっと見るときなどに役立ちます。



メインメニューに「9.項目別に見る」が加わりました。



9.を選択すると今度はどの項目を表示するかのメニューがでます。



では、プログラムを見てみましょう。

// jusho07.cpp #include <iostream.h> #include <fstream.h> #include <string.h> //memset()で必要 #include <conio.h> // getch()で必要 #include <stdio.h> // sprintf()で必要 #include <process.h> // system()で必要 #define JFILE "jfile.txt" class Jusho { struct _tagdata{ char name[64]; char address[256]; char birth_year[16]; char birth_month[8]; char birth_day[8]; char memo[256]; } data; char searchword[64]; public: Jusho(); int show(char *, char *); int write(); int search(); int edit(); int del(); int fileoutput(); int backup(); int sort1(); int itemview(); };

Jushoクラスにitemviewメンバ関数が増えました。また、showメンバ関数の 引数が変更になりました。これは、あとでこの関数を使って、ソートした 別ファイルの中身を表示するのに再利用します。2番目の引数は ファイル名を指定します。

Jusho::Jusho() { memset(&data, 0, sizeof(data)); }

コンストラクタには特に変更はありません。

int Jusho::show(char *sword, char *filename) { int n, i = 0, match; ifstream J; if (strcmp(sword, "") == 0) match = 2; J.open(filename, (ios::nocreate)); if (J.is_open()) J >> n; else { cout << "住所録データはありません" << endl; return -1; } while (i < n) { match = 0; J >> data.name; if (strstr(data.name, sword) != NULL) match = 1; J >> data.address; if (strstr(data.address, sword) != NULL) match = 1; J >> data.birth_year; if (strstr(data.birth_year, sword) != NULL) match = 1; J >> data.birth_month; if (strstr(data.birth_month, sword) != NULL) match = 1; J >> data.birth_day; if (strstr(data.birth_day, sword) != NULL) match = 1; J >> data.memo; if (strstr(data.memo, sword) != NULL) match = 1; if (match == 1 || match == 2) { cout << "----------------------" << endl; cout << data.name << endl; cout << data.address << endl; cout << data.birth_year << "年" << data.birth_month << "月" << data.birth_day << "日" << endl; cout << data.memo << endl; cout << "----------------------" << endl; cout << "Hit any key!" << endl; getch(); } i++; } J.close(); return 0; }

2番目の引数をファイル名としてオープンしている点が、今までと異なります。

int Jusho::write() { int no_of_data; char yesno[8]; ifstream Jin; ofstream Jout; Jin.open(JFILE, ios::nocreate); if (Jin.is_open() == 0) no_of_data = 0; else { Jin >> no_of_data; Jin.close(); } cout << "氏名--"; cin >> data.name; cout << "住所--"; cin >> data.address; cout << "誕生年--"; cin >> data.birth_year; cout << "誕生月--"; cin >> data.birth_month; cout << "誕生日--"; cin >> data.birth_day; cout << "メモを書き込みますか(1:Yes 0:NO)"; cin >> yesno; if (strcmp(yesno, "1") == 0) { cout << "メモ--"; cin >> data.memo; } else strcpy(data.memo, "メモなし"); Jout.open(JFILE, ios::ate); Jout.seekp(0); //ファイルの先頭に移動 Jout << no_of_data+1 << endl; Jout.seekp(0, ios::end); Jout << data.name << endl; Jout << data.address << endl; Jout << data.birth_year << endl; Jout << data.birth_month << endl; Jout << data.birth_day << endl; Jout << data.memo << endl; Jout.close(); return 0; }

このメンバ関数に変更はありません。

int Jusho::search() { int no, cont = 1; while (cont) { cout << endl; cout << "*******************" << endl; cout << "1.検索語句入力" << endl; cout << "0.終了" << endl; cout << "*******************" << endl; cout << "番号選択---"; cin >> no; switch (no) { case 0: cont = 0; break; case 1: cout << "検索語句---"; cin >> searchword; show(searchword, JFILE); break; default: cout << "番号が違います" << endl; getch(); break; } } return 0; }

showメンバ関数の引数が変更になったのに伴い、case 1 のところが

show(searchword, JFILE);

というように変更となりました。

int Jusho::edit() { int n, i = 0, komoku = 100, yes_no; char edit_name[64]; ifstream Jin; ofstream Jout; char *ptemp; cout << "編集するデータの氏名---"; cin >> edit_name; Jin.open(JFILE, (ios::nocreate)); if (Jin.is_open()) { Jin >> n; ptemp = new char[sizeof(data) * n]; sprintf(ptemp, "%d\n", n); } else { cout << "住所録データはありません" << endl; return -1; } while (i < n) { Jin >> data.name; Jin >> data.address; Jin >> data.birth_year; Jin >> data.birth_month; Jin >> data.birth_day; Jin >> data.memo; if (strstr(data.name, edit_name) != NULL) { cout << "*******************" << endl; cout << "1: " << data.name << endl; cout << "2: " << data.address << endl; cout << "3: " << data.birth_year << endl; cout << "4: " << data.birth_month << endl; cout << "5: " << data.birth_day << endl; cout << "6: " << data.memo << endl; cout << "*******************" << endl; cout << "このデータを編集しますか(1:Yes 0:No)"; cin >> yes_no; if (yes_no == 1) { while (1) { cout << "編集項目を指定してください(1-6, 0:終了)"; cin >> komoku; switch (komoku) { case 1: cout << "氏名--"; cin >> data.name; break; case 2: cout << "住所--"; cin >> data.address; break; case 3: cout << "誕生年--"; cin >> data.birth_year; break; case 4: cout << "誕生月--"; cin >> data.birth_month; break; case 5: cout << "誕生日--"; cin >> data.birth_day; break; case 6: cout << "メモ--"; cin >> data.memo; break; case 0: goto End; break; default: cout << "番号間違いです" << endl; break; }//switch(komoku) }//while() } // if データ編集するか }//if 部分一致 End: strcat(ptemp, data.name); strcat(ptemp, "\n"); strcat(ptemp, data.address); strcat(ptemp, "\n"); strcat(ptemp, data.birth_year); strcat(ptemp, "\n"); strcat(ptemp, data.birth_month); strcat(ptemp, "\n"); strcat(ptemp, data.birth_day); strcat(ptemp, "\n"); strcat(ptemp, data.memo); strcat(ptemp, "\n"); i++; } Jin.close(); Jout.open(JFILE, (ios::trunc)); Jout << ptemp; Jout.close(); delete [] ptemp; return 0; } int Jusho::del() { int i = 0, n, yes_no, no_of_data; char del_name[64]; ifstream Jin; ofstream Jout; char *ptemp; cout << "削除するデータの氏名---"; cin >> del_name; Jin.open(JFILE, (ios::nocreate)); if (Jin.is_open()) { Jin >> n; no_of_data = n; ptemp = new char[sizeof(data) * n]; ptemp[0] = '\0'; } else { cout << "住所録データはありません" << endl; return -1; } while (i < n) { Jin >> data.name; Jin >> data.address; Jin >> data.birth_year; Jin >> data.birth_month; Jin >> data.birth_day; Jin >> data.memo; if (strstr(data.name, del_name) != NULL) { cout << "*******************" << endl; cout << data.name << endl; cout << data.address << endl; cout << data.birth_year << endl; cout << data.birth_month << endl; cout << data.birth_day << endl; cout << data.memo << endl; cout << "*******************" << endl; cout << "このデータを削除しますか(1:Yes 0:No)"; cin >> yes_no; if (yes_no == 1) { cout << "OK" << endl; no_of_data--; goto End; } } strcat(ptemp, data.name); strcat(ptemp, "\n"); strcat(ptemp, data.address); strcat(ptemp, "\n"); strcat(ptemp, data.birth_year); strcat(ptemp, "\n"); strcat(ptemp, data.birth_month); strcat(ptemp, "\n"); strcat(ptemp, data.birth_day); strcat(ptemp, "\n"); strcat(ptemp, data.memo); strcat(ptemp, "\n"); End: i++; } Jin.close(); Jout.open(JFILE, (ios::trunc)); Jout << no_of_data << endl; Jout << ptemp; Jout.close(); delete [] ptemp; return 0; } int Jusho::fileoutput() { ifstream Jin; ofstream Jout; int n, i; char szYesNo[8]; char szBuf[256], szNewFile[64]; FILE *fp; Jin.open(JFILE, (ios::nocreate)); if (Jin.is_open()) { Jin >> n; } else { cout << "元になる住所録データがありません" << endl; return -1; } cout << "新しく作るファイル名-->"; cin >> szNewFile; if (strcmp(JFILE, szNewFile) == 0) { cout << "元になるファイルと同じ名前のファイルは作れません" << endl; Jin.close(); return -1; } fp = fopen(szNewFile, "r"); if (fp != NULL) { fclose(fp); cout << szNewFile << "はすでに存在します" << endl; cout << "上書きしますか(Y/N)-->"; cin >> szYesNo; if (strcmp(szYesNo, "n") == 0 || strcmp(szYesNo, "N")) { Jin.close(); return -1; } } Jout.open(szNewFile, (ios::trunc)); Jout << "*******************" << endl; for (i = 0; i < n; i++) { Jin >> szBuf; Jout << "[氏名] "; Jout << szBuf << endl;//名前 Jin >> szBuf; Jout << "[住所] "; Jout << szBuf << endl;//住所 Jin >> szBuf; Jout << "[生年月日] "; Jout << szBuf;//年 Jout << "/"; Jin >> szBuf; Jout << szBuf;//月 Jout << "/"; Jin >> szBuf; Jout << szBuf << endl;//日 Jin >> szBuf; Jout << "[メモ] "; Jout << szBuf << endl;//メモ Jout << "*******************" << endl; } Jin.close(); Jout.close(); return 0; } int Jusho::backup() { char szCommand[256], szBackup[64], szYesNo[8]; FILE *fp; cout << "バックアップファイル名-->"; cin >> szBackup; if (strcmp(JFILE, szBackup) == 0) { cout << "元ファイルと同じ名前のバックアップファイルは作れません" <<endl; return -1; } fp = fopen(szBackup, "r"); if (fp != NULL) { fclose(fp); cout << szBackup << " はすでに存在します" << endl; cout << "上書きしますか(Y/N)-->"; cin >> szYesNo; if (strcmp(szYesNo, "n") == 0 || strcmp(szYesNo, "N") == 0) return -1; } strcpy(szCommand, "copy "); strcat(szCommand, JFILE); strcat(szCommand, " "); strcat(szCommand, szBackup); cout << szCommand << endl; system(szCommand); return 0; }

これらのメンバ関数に変更はありません。

int Jusho::sort1() { struct _tagdata *mydata, temp; char szSortFile[64], birth1[32], birth2[32], szYesNo[8]; int key; int i, j, n, bExchange = 0; ifstream Jin; ofstream Jout; FILE *fp; Jin.open(JFILE, (ios::nocreate)); if (Jin.is_open()) { Jin >> n; mydata = new _tagdata[n]; } else { cout << "元になる住所録データがありません" << endl; return -1; } cout << "ソートしたデータを保存するファイル名-->"; cin >> szSortFile; fp = fopen(szSortFile, "r"); if (fp != NULL) { cout << szSortFile << "は、すでに存在します。" << endl; fclose(fp); return -1; } for (i = 0; i < n; i++) { Jin >> mydata[i].name; Jin >> mydata[i].address; Jin >> mydata[i].birth_year; Jin >> mydata[i].birth_month; Jin >> mydata[i].birth_day; Jin >> mydata[i].memo; } cout << "*******************" << endl; cout << "並び替えのキーを選択してください" << endl; cout << "1.氏名" << endl; cout << "2.住所" << endl; cout << "3.生年月日" << endl; cout << "4.メモ" << endl; cout << "*******************" << endl; cout << "キー-->"; cin >> key; for (i = 0; i < n - 1; i++) { for (j = i + 1; j < n; j++) { switch (key) { case 1: if (strcmp(mydata[i].name, mydata[j].name) > 0) { temp = mydata[i]; mydata[i] = mydata[j]; mydata[j] = temp; } break; case 2: if (strcmp(mydata[i].address, mydata[j].address) > 0) { temp = mydata[i]; mydata[i] = mydata[j]; mydata[j] = temp; } break; case 3: strcpy(birth1, mydata[i].birth_year); strcat(birth1, mydata[i].birth_month); strcat(birth1, mydata[i].birth_day); strcpy(birth2, mydata[j].birth_year); strcat(birth2, mydata[j].birth_month); strcat(birth2, mydata[j].birth_day); if (strcmp(birth1, birth2) > 0) { temp = mydata[i]; mydata[i] = mydata[j]; mydata[j] = temp; } break; case 4: if (strcmp(mydata[i].memo, mydata[j].memo) > 0) { temp = mydata[i]; mydata[i] = mydata[j]; mydata[j] = temp; } break; default: cout << "Error" << endl; delete [] mydata; return -1; } } } Jout.open(szSortFile, (ios::trunc)); Jout << n << endl; for (i = 0; i < n; i++) { Jout << mydata[i].name << endl; Jout << mydata[i].address << endl; Jout << mydata[i].birth_year << endl;; Jout << mydata[i].birth_month << endl; Jout << mydata[i].birth_day << endl; Jout << mydata[i].memo << endl; } Jout.close(); delete [] mydata; cout << "ソートした内容を見ますか(Y/N)-->"; cin >> szYesNo; if (strcmp(szYesNo, "Y") == 0 || strcmp(szYesNo, "y") == 0) show("", szSortFile); return 0; }

最後の方に、ソートした内容を見る場合はshow("", szSortFile);を実行して 簡単に内容を見ることができるようにしました。

int Jusho::itemview() { int n, i; char no[8]; ifstream J; cout << "*******************" << endl; cout << "1.氏名" << endl; cout << "2.住所" << endl; cout << "3.生年月日" << endl; cout << "4.メモ" << endl; cout << "*******************" << endl; cout << "選択番号-->"; cin >> no; if (strcmp(no, "1") != 0 && strcmp(no, "2") != 0 && strcmp(no, "3") != 0 && strcmp(no, "4") != 0) { cout << endl; cout << "番号入力エラーです" << endl; return -1; } J.open(JFILE, (ios::nocreate)); if (J.is_open()) J >> n; else { cout << "住所録データはありません" << endl; return -1; } for (i = 0; i < n; i++) { J >> data.name; if (strcmp(no, "1") == 0) { cout << i + 1 << ":"; cout << data.name << endl; } J >> data.address; if (strcmp(no, "2") == 0) { cout << i + 1 << ":"; cout << data.address << endl; } J >> data.birth_year; J >> data.birth_month; J >> data.birth_day; if (strcmp(no, "3") == 0) { cout << i + 1 << ":"; cout << data.birth_year << "年" << data.birth_month << "月" << data.birth_day << "日" << endl; } J >> data.memo; if (strcmp(no, "4") == 0) { cout << i + 1 << ":"; cout << data.memo << endl; } } J.close(); cout << "Hit any key!" << endl; getch(); return 0; }

項目別に表示する関数です。一行ずつ見ていくと別にどうということはないですね。 サブメニューで選択した番号以外は、coutしていないだけです。

int main() { Jusho j; int no, cont = 1; while (cont) { cout << endl; cout << "*******************" << endl; 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 << "0.終了" << endl; cout << "*******************" << endl; cout << "番号選択---"; cin >> no; switch (no) { case 0: cont = 0; break; case 1: j.show("", JFILE); break; case 2: j.write(); break; case 3: j.search(); break; case 4: j.edit(); break; case 5: j.del(); break; case 6: j.fileoutput(); break; case 7: j.backup(); break; case 8: j.sort1(); break; case 9: j.itemview(); break; default: cout << "番号が違います" << endl; break; } } return 0; }

main関数です。

メニュー項目の9が増えました。

いろいろ不満の多いプログラムですが、使いやすいように改良してみてください。


[C++Index] [総合Index] [Previous Chapter] [Next Chapter]

Update Apr/30/2001 By Y.Kumei
当ホーム・ページの一部または全部を無断で複写、複製、 転載あるいはコンピュータ等のファイルに保存することを禁じます。