📜  使用文件处理的C++中的通讯录(1)

📅  最后修改于: 2023-12-03 15:36:39.882000             🧑  作者: Mango

使用文件处理的 C++ 中的通讯录

简介

本文介绍如何使用 C++ 文件处理来创建一个通讯录。通讯录存储联系人的姓名和电话号码,支持添加、删除、修改和查找联系人的功能。所有联系人信息都存储在一个文本文件中,方便以后的读取和修改操作。

功能列表

以下是该通讯录程序支持的功能列表:

  • 添加联系人
  • 删除联系人
  • 修改联系人
  • 查找联系人
  • 显示所有联系人
实现方法
文件结构

我们首先定义一个 Contact 结构体来表示每个联系人的信息:

struct Contact {
    std::string name;
    std::string phone;
};

然后我们用一个文件来存储所有联系人的信息。文件的格式为:

name1 phone1
name2 phone2
...
读取联系人列表

通讯录的第一步是读取文件中的联系人列表。我们可以使用 C++ 的文件读取来实现该功能:

std::vector<Contact> ReadContacts(const std::string& filename) {
    std::vector<Contact> contacts;
    std::ifstream input(filename);
    if (!input.is_open()) {
        std::cerr << "Could not open file: " << filename << '\n';
        return contacts;
    }
    std::string name, phone;
    while (input >> name >> phone) {
        contacts.push_back({name, phone});
    }
    input.close();
    return contacts;
}

该函数返回一个 std::vector<Contact>,表示文件中的所有联系人。

添加联系人

要添加联系人,我们需要读取用户输入的联系人信息,并将其添加到文件末尾。我们可以使用 C++ 的文件写入来实现该功能:

bool AddContact(const std::string& filename, const Contact& contact) {
    std::ofstream output(filename, std::ios::app);
    if (!output.is_open()) {
        std::cerr << "Could not open file: " << filename << '\n';
        return false;
    }
    output << contact.name << ' ' << contact.phone << '\n';
    output.close();
    return true;
}

该函数将联系人信息添加到文件末尾,并返回操作是否成功的布尔值。

删除联系人

要删除联系人,我们需要读取用户输入的联系人姓名,并从文件中删除该联系人。我们可以先读取文件中的所有联系人信息,然后在内存中删除该联系人,并覆盖原有的文件。

bool DeleteContact(const std::string& filename, const std::string& name) {
    std::vector<Contact> contacts = ReadContacts(filename);
    bool found = false;
    for (auto it = contacts.begin(); it != contacts.end(); ++it) {
        if (it->name == name) {
            contacts.erase(it);
            found = true;
            break;
        }
    }
    if (!found) {
        std::cerr << "Contact not found: " << name << '\n';
        return false;
    }
    std::ofstream output(filename);
    if (!output.is_open()) {
        std::cerr << "Could not open file: " << filename << '\n';
        return false;
    }
    for (const auto& contact : contacts) {
        output << contact.name << ' ' << contact.phone << '\n';
    }
    output.close();
    return true;
}

该函数返回操作是否成功的布尔值。

修改联系人

要修改联系人,我们需要读取用户输入的联系人姓名,并将其对应的联系人信息修改后写回文件。我们可以先读取文件中的所有联系人信息,然后在内存中修改该联系人信息,并覆盖原有的文件。

bool ModifyContact(const std::string& filename, const std::string& name,
                   const Contact& new_contact) {
    std::vector<Contact> contacts = ReadContacts(filename);
    bool found = false;
    for (auto& contact : contacts) {
        if (contact.name == name) {
            contact = new_contact;
            found = true;
            break;
        }
    }
    if (!found) {
        std::cerr << "Contact not found: " << name << '\n';
        return false;
    }
    std::ofstream output(filename);
    if (!output.is_open()) {
        std::cerr << "Could not open file: " << filename << '\n';
        return false;
    }
    for (const auto& contact : contacts) {
        output << contact.name << ' ' << contact.phone << '\n';
    }
    output.close();
    return true;
}

该函数返回操作是否成功的布尔值。

查找联系人

要查找联系人,我们需要读取用户输入的联系人姓名,并在文件中查找该联系人的信息。我们可以先读取文件中的所有联系人信息,并在内存中查找该联系人的信息。

std::vector<Contact> FindContacts(const std::string& filename,
                                   const std::string& name) {
    std::vector<Contact> contacts = ReadContacts(filename);
    std::vector<Contact> result;
    for (const auto& contact : contacts) {
        if (contact.name.find(name) != std::string::npos) {
            result.push_back(contact);
        }
    }
    return result;
}

该函数返回一个 std::vector<Contact>,表示文件中所有匹配的联系人。

显示所有联系人

要显示所有联系人,我们可以读取文件中的所有联系人信息并输出到屏幕上。

void ShowAllContacts(const std::string& filename) {
    std::vector<Contact> contacts = ReadContacts(filename);
    for (const auto& contact : contacts) {
        std::cout << contact.name << ' ' << contact.phone << '\n';
    }
}
完整代码
#include <fstream>
#include <iostream>
#include <string>
#include <vector>

struct Contact {
    std::string name;
    std::string phone;
};

std::vector<Contact> ReadContacts(const std::string& filename) {
    std::vector<Contact> contacts;
    std::ifstream input(filename);
    if (!input.is_open()) {
        std::cerr << "Could not open file: " << filename << '\n';
        return contacts;
    }
    std::string name, phone;
    while (input >> name >> phone) {
        contacts.push_back({name, phone});
    }
    input.close();
    return contacts;
}

bool AddContact(const std::string& filename, const Contact& contact) {
    std::ofstream output(filename, std::ios::app);
    if (!output.is_open()) {
        std::cerr << "Could not open file: " << filename << '\n';
        return false;
    }
    output << contact.name << ' ' << contact.phone << '\n';
    output.close();
    return true;
}

bool DeleteContact(const std::string& filename, const std::string& name) {
    std::vector<Contact> contacts = ReadContacts(filename);
    bool found = false;
    for (auto it = contacts.begin(); it != contacts.end(); ++it) {
        if (it->name == name) {
            contacts.erase(it);
            found = true;
            break;
        }
    }
    if (!found) {
        std::cerr << "Contact not found: " << name << '\n';
        return false;
    }
    std::ofstream output(filename);
    if (!output.is_open()) {
        std::cerr << "Could not open file: " << filename << '\n';
        return false;
    }
    for (const auto& contact : contacts) {
        output << contact.name << ' ' << contact.phone << '\n';
    }
    output.close();
    return true;
}

bool ModifyContact(const std::string& filename, const std::string& name,
                   const Contact& new_contact) {
    std::vector<Contact> contacts = ReadContacts(filename);
    bool found = false;
    for (auto& contact : contacts) {
        if (contact.name == name) {
            contact = new_contact;
            found = true;
            break;
        }
    }
    if (!found) {
        std::cerr << "Contact not found: " << name << '\n';
        return false;
    }
    std::ofstream output(filename);
    if (!output.is_open()) {
        std::cerr << "Could not open file: " << filename << '\n';
        return false;
    }
    for (const auto& contact : contacts) {
        output << contact.name << ' ' << contact.phone << '\n';
    }
    output.close();
    return true;
}

std::vector<Contact> FindContacts(const std::string& filename,
                                   const std::string& name) {
    std::vector<Contact> contacts = ReadContacts(filename);
    std::vector<Contact> result;
    for (const auto& contact : contacts) {
        if (contact.name.find(name) != std::string::npos) {
            result.push_back(contact);
        }
    }
    return result;
}

void ShowAllContacts(const std::string& filename) {
    std::vector<Contact> contacts = ReadContacts(filename);
    for (const auto& contact : contacts) {
        std::cout << contact.name << ' ' << contact.phone << '\n';
    }
}

int main() {
    const std::string kFilename = "contacts.txt";

    while (true) {
        std::cout << "(A)dd, (D)elete, (M)odify, (F)ind, (S)how all, or (Q)uit? ";
        char choice;
        std::cin >> choice;
        if (choice == 'Q' || choice == 'q') {
            break;
        }
        switch (choice) {
            case 'A':
            case 'a': {
                std::cout << "Name: ";
                std::string name;
                std::cin >> name;
                std::cout << "Phone: ";
                std::string phone;
                std::cin >> phone;
                Contact contact{name, phone};
                if (AddContact(kFilename, contact)) {
                    std::cout << "Contact added.\n";
                }
                break;
            }
            case 'D':
            case 'd': {
                std::cout << "Name: ";
                std::string name;
                std::cin >> name;
                if (DeleteContact(kFilename, name)) {
                    std::cout << "Contact deleted.\n";
                }
                break;
            }
            case 'M':
            case 'm': {
                std::cout << "Name: ";
                std::string name;
                std::cin >> name;
                std::cout << "New name: ";
                std::string new_name;
                std::cin >> new_name;
                std::cout << "New phone: ";
                std::string new_phone;
                std::cin >> new_phone;
                Contact new_contact{new_name, new_phone};
                if (ModifyContact(kFilename, name, new_contact)) {
                    std::cout << "Contact modified.\n";
                }
                break;
            }
            case 'F':
            case 'f': {
                std::cout << "Name: ";
                std::string name;
                std::cin >> name;
                std::vector<Contact> contacts = FindContacts(kFilename, name);
                if (contacts.empty()) {
                    std::cout << "No matching contacts found.\n";
                } else {
                    for (const auto& contact : contacts) {
                        std::cout << contact.name << ' ' << contact.phone << '\n';
                    }
                }
                break;
            }
            case 'S':
            case 's': {
                ShowAllContacts(kFilename);
                break;
            }
            default:
                std::cerr << "Invalid choice.\n";
        }
    }

    return 0;
}
总结

通过本文,我们了解到了如何使用 C++ 的文件处理来创建一个简单的通讯录。这个通讯录支持添加、删除、修改、查找和显示所有联系人的功能。我们使用了 C++ 的文件读取和文件写入来实现文件的输入输出。文件结构采用了简单的行格式,方便读写和修改。