プロジェクト:アドレス帳
[第]50[課では]ユニットテストについて学びました。
[現在]、[私たちは][最初の総合]実践プロジェクト――[アドレス帳システム]に取り組みます。
[この]プロジェクト[では、これまでに学んだすべての知識を総合的に活用することになります]。
1. プロジェクト[要件]
(1) 1.1 [機能要件]
| [機能] | [説明] |
|---|---|
| [連絡先を追加] | [氏名]、[電話番号]、[メールアドレス] |
| [連絡先を削除] | [名前または電話番号で削除] |
| [連絡先を編集] | [情報を編集] |
| [連絡先を検索] | [名前または電話番号で検索] |
| [すべて表示] | [すべての連絡先を表示] |
| [保存]/[読み込み] | [保存先]file |
(2) 1.2 クラス[の設計]
Contact()
- name, phone, email
AddressBook()
- vectorContact contacts
- add, remove, update, find, display
- save, load
2. [連絡先]クラス
(1) 2.1 Contactclass[定義]
#include iostream
#include string
#include fstream
class Contact {
private:
std::string name;
std::string phone;
std::string email;
public:
Contact() = default;
Contact(const std::string& name, const std::string& phone, const std::string& email)
: name(name), phone(phone), email(email) {}
// Getter
std::string getName() const { return name; }
std::string getPhone() const { return phone; }
std::string getEmail() const { return email; }
// Setter
void setName(const std::string& n) { name = n; }
void setPhone(const std::string& p) { phone = p; }
void setEmail(const std::string& e) { email = e; }
// ...
void display() const {
std::cout << ":" << name << std::endl;
std::cout << ":" << phone << std::endl;
std::cout << ":" << email << std::endl;
std::cout << "-------------------" << std::endl;
}
// ()
void save(std::ofstream& file) const {
file << name << "," << phone << "," << email << std::endl;
}
// ()
static Contact load(std::ifstream& file) {
Contact c;
std::getline(file, c.name, ',');
std::getline(file, c.phone, ',');
std::getline(file, c.email);
return c;
}
};
3. [連絡先]クラス
(1) 3.1 AddressBookクラス[定義]
▶ サンプル 1: STLコンテナ[使用] (難易度 ⭐)
#include vector
#include algorithm
class AddressBook {
private:
std::vectorContact contacts;
public:
// ...
void addContact(const Contact& c) {
contacts.push_back(c);
std::cout << "!" << std::endl;
}
// ()
Contact* findByName(const std::string& name) {
for (auto& c : contacts) {
if (c.getName() == name) {
return &c;
}
}
return nullptr;
}
// ()
bool removeByName(const std::string& name) {
auto it = std::remove_if(contacts.begin(), contacts.end(),
[&name](const Contact& c) {
return c.getName() == name;
});
if (it != contacts.end()) {
contacts.erase(it, contacts.end());
std::cout << "!" << std::endl;
return true;
}
std::cout << ":" << name << std::endl;
return false;
}
// ...
void displayAll() const {
if (contacts.empty()) {
std::cout << "..." << std::endl;
return;
}
for (const auto& c : contacts) {
c.display();
}
}
// ...
void saveToFile(const std::string& filename) const {
std::ofstream file(filename);
if (!file) {
std::cerr << "..." << std::endl;
return;
}
for (const auto& c : contacts) {
c.save(file);
}
file.close();
std::cout << "!" << std::endl;
}
// ...
void loadFromFile(const std::string& filename) {
std::ifstream file(filename);
if (!file) {
std::cerr << "..." << std::endl;
return;
}
contacts.clear(); // ...
std::string line;
while (file.peek() != EOF) {
contacts.push_back(Contact::load(file));
}
file.close();
std::cout << "!" << std::endl;
}
};
4. [メインメニュー]
(1) 4.1 [メニューの実装]
void showMenu() {
### (2) ▶ 2:(⭐)
std::cout << "\n===== =====" << std::endl;
std::cout << "1." << std::endl;
std::cout << "2." << std::endl;
std::cout << "3." << std::endl;
std::cout << "4." << std::endl;
std::cout << "5." << std::endl;
std::cout << "6." << std::endl;
std::cout << "0." << std::endl;
std::cout << "==========================" << std::endl;
std::cout << ":";
}
int main() {
AddressBook book;
int choice;
do {
showMenu();
std::cin >> choice;
switch (choice) {
case 1: {
std::string name, phone, email;
std::cout << ":";
std::cin >> name;
std::cout << ":";
std::cin >> phone;
std::cout << ":";
std::cin >> email;
book.addContact(Contact(name, phone, email));
break;
}
case 2: {
std::string name;
std::cout << ":";
std::cin >> name;
book.removeByName(name);
break;
}
case 3: {
std::string name;
std::cout << ":";
std::cin >> name;
Contact* c = book.findByName(name);
if (c) {
c->display();
} else {
std::cout << "..." << std::endl;
}
break;
}
case 4:
book.displayAll();
break;
case 5: {
book.saveToFile("contacts.txt");
break;
}
case 6: {
book.loadFromFile("contacts.txt");
break;
}
case 0:
std::cout << "!" << std::endl;
break;
default:
std::cout << "..." << std::endl;
}
} while (choice != 0);
return 0;
}
5. [拡張提案]
(1) 5.1 [機能拡張]
| [機能] | [難易度] |
|---|---|
| [電話番号で検索] | ⭐ |
| [連絡先を編集] | ⭐⭐ |
| [氏名順] | ⭐⭐ |
| [CSVのインポート]/[CSVのエクスポート] | ⭐⭐⭐ |
| [グラフィカルユーザーインターフェース] | ⭐⭐⭐⭐ |
6. ❓ [練習]
(1) [基礎練習] (難易度 ⭐)
[連絡先に追加]、「[電話番号で検索]」、「[機能]」。
(2) [上級練習] (難易度 ⭐⭐)
[アドレス帳に追加]「[連絡先を編集]」「[機能]」。
(3) [チャレンジ問題] (難易度 ⭐⭐⭐)
[使用] std::map [アドレス帳の再構築]、[検索効率の向上]。
❓ よくある質問
Q:practice address bookについて最も重要なことは何ですか? A:まず核心概念を理解し、その後実践的な例で練習することが重要です。
Q:practice address bookを効果的に練習するにはどうすればよいですか? A:簡単な例から始め、徐々に複雑さを増やし、常にコードをテストしてください。
Q:practice address bookでよくある間違いは何ですか? A:コンパイラのエラーメッセージを注意深く読み、変数は使用前に必ず初期化してください。
📖 まとめ
| [知識ポイント] | [応用] |
|---|---|
| オブジェクト指向 | Contact[和]AddressBookクラス |
| STL | vector[連絡先を格納] |
| ファイル[操作] | [保存]/[読み込み] |
| 文字列[処理] | [解析]CSV |
- [アドレス帳システム]:[追加・削除・変更・検索の4大基本機能]
- [用]struct[連絡先情報を格納する]
- ベクトルコンテナ[動的データの管理]
- ファイル[読み書きによるデータの永続化の実現]
- [モジュール化]機能のカプセル化[各機能]
📝 練習問題
-
初心者(難易度 ⭐): [アドレス帳]アプリを起動し、[連絡先]を3件[追加]([氏名]、[電話番号]、[グループ])して、[表示結果を確認]します。[「編集」]機能を使って、そのうちの1件の連絡先情報を[変更]してみてください。
-
中級(難易度 ⭐⭐): [連絡先に追加]「[お気に入り連絡先]」[機能]――[struct内に]
bool isFavorite[フィールド]を追加し、[リスト表示時に、お気に入り連絡先を][★]とマークする。 -
上級(難易度 ⭐⭐⭐): [実装]「[あいまい検索]」[機能]:[ユーザーが]キーワードを入力すると、[そのキーワードを含むすべての氏名の連絡先を照合して表示する]。[もし]入力が空の場合、[すべてを表示する]。[大文字と小文字を区別しない検索に対応している]。
[次のレッスン]:演習:[簡易データベース](#52)



