​7.1 项目1 学生通讯录管理:文本文件增删改查(C++版本)(自顶向下设计+断点调试) (A)​

2023-11-18

C++自学精简教程 目录(必读)

作业目标:

这个作业中,你需要综合运用之前文章中的知识,来解决一个相对完整的应用程序。

作业描述:

1 在这个作业中你需要在文本文件中存储学生通讯录的信息,并在程序启动的时候加载这些数据到内存中。

2 在程序运行过程中允许用户用键盘输入信息来完成对通讯录数的增删改查。

交互示例:

开始代码

开始代码不是完整的代码,需要你填写一部分代码,使之完整。

答案在本文最后

当你填写完整之后,运行程序和示例的交互输出一致,就算完成了这个作业

开始代码:

#include <iostream>
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <fstream>
using namespace std;

class Person
{
public:
    friend ostream& operator<<(ostream& os, const Person& _person);
    friend istream& operator>>(istream& is, Person& _person);

public:
    string m_id;
    string m_name;
    string m_tel;
};

ostream& operator<<(ostream& os, const Person& person)
{
    os << left << setw(5) << person.m_id << setw(15) << person.m_name << setw(20) << person.m_tel;
    return os;
}

istream& operator>>(istream& is, Person& person)
{
    //(1) your code 
    // 使用输入操作符重载,将流中的数据,提取赋值给person对象的成员变量中
    //see https://zhuanlan.zhihu.com/p/412724745

    return is;
}

class PersonManager
{
public:
    void InputOnePerson(void);
    bool LoadAllPersonFromFile(const string& fileName);
    bool DeletePerson(void);
    bool QueryPersonByName() const;
    bool QueryPersonByTel() const;
    void ShowAllPerson(void) const;
    bool SaveAllPersonToFile(void) const;

private:
    vector<Person> m_allPerson;
};

bool PersonManager::DeletePerson(void)
{
    cout << "Please input person id for delete:";


    string id;
    cin >> id;
    for (auto itr = m_allPerson.begin(); itr != m_allPerson.cend(); ++itr)
    {
        if (itr->m_id == id)
        {
            //(2) your code
            // 容器的erase方法支持删除容器的元素时,传入指向元素的迭代器
            //see https://zhuanlan.zhihu.com/p/441293600

        }
    }
    return false;
}
bool PersonManager::QueryPersonByName() const
{
    //注意该函数需要返回bool值
    cout << "Please input name for query:";
    
    string name;
    cin >> name;
    for (auto itr = m_allPerson.cbegin(); itr != m_allPerson.cend(); ++itr)
    {
        if (itr->m_name == name)
        {
            cout << "Find:" << endl;
            //(3) your code
            //see https://zhuanlan.zhihu.com/p/376440190
            //see https://zhuanlan.zhihu.com/p/376446724

        }
    }
    cout << "not found " << name << endl;
    return false;
}
bool PersonManager::QueryPersonByTel() const
{
    cout << "Please input tel for query:";
    string tel;
    cin >> tel;
    for (auto itr = m_allPerson.cbegin(); itr != m_allPerson.cend(); ++itr)
    {
        if (itr->m_tel == tel)
        {
            cout << "Find:" << endl;
            //(4) your code
            //see https://zhuanlan.zhihu.com/p/376440190
            //see https://zhuanlan.zhihu.com/p/376446724

        }
    }
    cout << "not found " << tel << endl;
    return false;
}

void PersonManager::ShowAllPerson(void) const
{
    cout << "All Person:" << endl;
    cout << left << setw(5) << "id" << setw(15) << "name" << setw(20) << "tel" << endl;
    for (auto& item : m_allPerson)
    {
        cout << item << endl;
    }
}
bool PersonManager::SaveAllPersonToFile(void) const
{
    ofstream fout("data_saved.txt");
    //下面的常量迭代器 cbegin cend 中的 c 指的是 const的意思,表示不可以修改容器的元素
    for (auto itr = m_allPerson.cbegin(); itr != m_allPerson.cend(); ++itr)
    {
        //(5) your code 
        //see https://zhuanlan.zhihu.com/p/262508774

    }
    return true;
}

bool PersonManager::LoadAllPersonFromFile(const string& fileName)
{
    ifstream fin(fileName);
    if (!fin)
    {
        cout << "load data failed . file " << fileName << " not exits." << endl;
        return false;
    }

    Person person;
    while (fin >> person)
    {
        m_allPerson.push_back(person);
    }
    cout << "load data from file success." << endl;
    return true;
}

void PersonManager::InputOnePerson(void)
{
    cout << "Please input one person:" << endl;
    cout << "Please input id:";
    string id;
    cin >> id;
    Person person;
    person.m_id = id;

    for (auto itr = m_allPerson.cbegin(); itr != m_allPerson.cend(); ++itr)
    {
        if (itr->m_id == id)
        {
            cout << id << " already existed! Save failed." << endl;
            return;
        }
    }

    cout << "Please input name:";
    string name;
    cin >> name;
    person.m_name = name;

    cout << "Please input tel:";
    string tel;
    cin >> tel;
    person.m_tel = tel;

    cout << "Input finished, save successed." << endl;

    m_allPerson.push_back(person);
}

int main(int argv, char* argc[])
{
    PersonManager personMgr;
    personMgr.LoadAllPersonFromFile("input_data.txt");
    personMgr.ShowAllPerson();
    
    while(true)
    {
        cout<<"input a commond : "<<endl;
        cout<<"1 [AddPerson]"<<endl;
        cout<<"2 [ShowAllPerson]"<<endl;
        cout<<"3 [QueryPerson by name]"<<endl;
        cout<<"4 [QueryPerson by tel]"<<endl;
        cout<<"5 [SaveAllPersonToFile]"<<endl;
        cout<<"6 [DeletePerson]"<<endl;
        cout<<"0 [ExitAndSaveChange]"<<endl;
        int commond;
        cin>>commond;
        switch(commond)
        {
        case 1: { personMgr.InputOnePerson(); break;}
        case 2: { personMgr.ShowAllPerson(); break;}
        case 3: { personMgr.QueryPersonByName(); break;}
        case 4: { personMgr.QueryPersonByTel(); break;}
        case 5: { personMgr.SaveAllPersonToFile(); break;}
        case 6: { personMgr.DeletePerson(); break;}
        case 0: { personMgr.SaveAllPersonToFile(); return 0;}
        default:{ cout<<"System Exit."<<endl; return 0;}
        }
    }
    return 0;
}

输入文件

input_data.txt

文件内容:

2    zhangsan2      13788889992         
3    zhangsan3      13788889993         
4    zhangsan4      13788889994         
5    wanger         13333333333      

运行与输出

load data from file success.
All Person:
id   name           tel
2    zhangsan2      13788889992
3    zhangsan3      13788889993
4    zhangsan4      13788889994
5    wanger         13333333333
input a commond :
1 [AddPerson]
2 [ShowAllPerson]
3 [QueryPerson by name]
4 [QueryPerson by tel]
5 [SaveAllPersonToFile]
6 [DeletePerson]
0 [ExitAndSaveChange]
2
All Person:
id   name           tel
2    zhangsan2      13788889992
3    zhangsan3      13788889993
4    zhangsan4      13788889994
5    wanger         13333333333
input a commond :
1 [AddPerson]
2 [ShowAllPerson]
3 [QueryPerson by name]
4 [QueryPerson by tel]
5 [SaveAllPersonToFile]
6 [DeletePerson]
0 [ExitAndSaveChange]
1
Please input one person:
Please input id:1
Please input name:zhangsan
Please input tel:13344445555
Input finished, save successed.
input a commond :
1 [AddPerson]
2 [ShowAllPerson]
3 [QueryPerson by name]
4 [QueryPerson by tel]
5 [SaveAllPersonToFile]
6 [DeletePerson]
0 [ExitAndSaveChange]
2
All Person:
id   name           tel
2    zhangsan2      13788889992
3    zhangsan3      13788889993
4    zhangsan4      13788889994
5    wanger         13333333333
1    zhangsan       13344445555
input a commond :
1 [AddPerson]
2 [ShowAllPerson]
3 [QueryPerson by name]
4 [QueryPerson by tel]
5 [SaveAllPersonToFile]
6 [DeletePerson]
0 [ExitAndSaveChange]
3
Please input name for query:zhangsan
Find:
1    zhangsan       13344445555
input a commond :
1 [AddPerson]
2 [ShowAllPerson]
3 [QueryPerson by name]
4 [QueryPerson by tel]
5 [SaveAllPersonToFile]
6 [DeletePerson]
0 [ExitAndSaveChange]
3
Please input name for query:zhang
not found zhang
input a commond :
1 [AddPerson]
2 [ShowAllPerson]
3 [QueryPerson by name]
4 [QueryPerson by tel]
5 [SaveAllPersonToFile]
6 [DeletePerson]
0 [ExitAndSaveChange]
4
Please input tel for query:13344445555
Find:
1    zhangsan       13344445555
input a commond :
1 [AddPerson]
2 [ShowAllPerson]
3 [QueryPerson by name]
4 [QueryPerson by tel]
5 [SaveAllPersonToFile]
6 [DeletePerson]
0 [ExitAndSaveChange]
4
Please input tel for query:1334444
not found 1334444
input a commond :
1 [AddPerson]
2 [ShowAllPerson]
3 [QueryPerson by name]
4 [QueryPerson by tel]
5 [SaveAllPersonToFile]
6 [DeletePerson]
0 [ExitAndSaveChange]
6
Please input person id for delete:4
input a commond :
1 [AddPerson]
2 [ShowAllPerson]
3 [QueryPerson by name]
4 [QueryPerson by tel]
5 [SaveAllPersonToFile]
6 [DeletePerson]
0 [ExitAndSaveChange]
2
All Person:
id   name           tel
2    zhangsan2      13788889992
3    zhangsan3      13788889993
5    wanger         13333333333
1    zhangsan       13344445555
input a commond :
1 [AddPerson]
2 [ShowAllPerson]
3 [QueryPerson by name]
4 [QueryPerson by tel]
5 [SaveAllPersonToFile]
6 [DeletePerson]
0 [ExitAndSaveChange]
5
input a commond :
1 [AddPerson]
2 [ShowAllPerson]
3 [QueryPerson by name]
4 [QueryPerson by tel]
5 [SaveAllPersonToFile]
6 [DeletePerson]
0 [ExitAndSaveChange]
0

最终保存数据到文件 data_saved.txt

文件 data_saved.txt 的内容为:

2    zhangsan2      13788889992         
3    zhangsan3      13788889993         
5    wanger         13333333333         
1    zhangsan       13344445555       

你的结果也是这样吗?

答案在此

C++自学精简教程 全部答案

学生完成该作业展示

另一个学生实现的效果

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

​7.1 项目1 学生通讯录管理:文本文件增删改查(C++版本)(自顶向下设计+断点调试) (A)​ 的相关文章

  • 如何在 DataColumn.Expression 中使用 IF/ELSE 或 CASE?

    我有一个包含 1 列的表 状态 我想添加另一列名为 Action 的列 其值如下 如果 Status Yes 则 Action Go 否则 Action Stop 我使用以下代码添加到 操作 列中 但它不起作用 myDataTable Co
  • 有没有快速创建集合的方法?

    目前我正在创建一个像这样的新集 std set a s s insert a1 s insert a2 s insert a3 s insert a10 有没有办法创建s在一行 int myints 10 20 30 40 50 std s
  • QCombobox 向下箭头图像

    如何更改Qcombobox向下箭头图像 现在我正在使用这个 QSS 代码 但这不起作用 我无法删除向下箭头边框 QComboBox border 0px QComboBox down arrow border 0px background
  • 如何保证对象只有一个线程

    我有以下代码 class Service public void start creates thread which creates window and goes to message loop void stop sends WM C
  • 我如何理解这个 C 类型声明?

    double bar int double double double double 在查看讲座幻灯片时 我发现了留给学生的练习 用简单的英语来说 什么是类型bar在这个 C 声明中 Please帮助我解决这个问题 我什至不知道从哪里开始
  • 何时使用 =default 使析构函数默认?

    尽管对构造函数使用 default 对我来说很清楚 即强制编译器在其他构造函数存在时创建默认构造函数 但我仍然无法理解这两种类型的析构函数之间的区别 那些使用 default 的 那些没有显式定义并由编译器自动生成的 我唯一想到的是 gro
  • FileStream 构造函数和默认缓冲区大小

    我们有一个使用 NET 4 用 C 编写的日志记录类 我想添加一个构造函数参数 该参数可以选择设置文件选项 WriteThrough http msdn microsoft com en us library system io fileo
  • 更改 Qt OpenGL 窗口示例以使用 OpenGL 3.3

    我正在尝试更改 Qt OpenGL 示例以使用更现代的 opengl 版本 330 似乎合适 所以我做了 在 main cpp 上设置版本和配置文件 设置着色器版本 更改着色器以使用统一 它现在构建没有任何错误 但我只看到一个空白窗口 我错
  • VS 程序在调试模式下崩溃,但在发布模式下不崩溃?

    我正在 VS 2012 中运行以下程序来尝试 Thrust 函数查找 include cuda runtime h include device launch parameters h include
  • 我如何在 C# .NET(win7 手机)中使用“DataContractJsonSerializer”读入“嵌套”Json 文件?

    我有一个问题 如果我的 json 文件看起来像这样 Numbers 45387 Words 空间桶 我可以很好地阅读它 但是如果它看起来像这样 Main Numbers 45387 Words 空间桶 某事 数字 12345 单词 克兰斯基
  • 信号处理程序有单独的堆栈吗?

    信号处理程序是否有单独的堆栈 就像每个线程都有单独的堆栈一样 这是在 Linux C 环境中 来自 Linux 手册页signal 7 http kernel org doc man pages online pages man7 sign
  • 如何在 C# 控制台应用程序中将修饰符(ctrl、alt、shift)按键捕获为单个按键?

    Console ReadKey 仅在按下 正常 键时捕获输入 然后将修饰符 如果有 附加为键信息的一部分 如何将单个修饰键注册为输入 提供了一种解决方案这个链接 https blogs msdn microsoft com toub 200
  • 类的成员复制

    在学习 复制成员 概念时 书中给出了如下说法 此外 如果非静态成员是引用 const 或没有复制赋值的用户定义类型 则无法生成默认赋值 我不太明白这个声明到底想传达什么 或者说这个说法指的是哪一种场景 谢谢 该语句与编译器自动为您编写的类
  • 从 WebBrowser 控件 C# 获取滚动值

    我试图在 WebBrowser 控件中获取网页的 Y 滚动索引 但无法访问内置滚动条的值 有任何想法吗 对于标准模式下的 IE 使用文档类型 正如你所说 scrollTop是的财产元素 而不是 HtmlDocument htmlDoc th
  • 检查 RoutedEvent 是否有任何处理程序

    我有一个自定义 Button 类 当单击它时 打开特定窗口 它总是执行相同的操作 我添加了一个可以在按钮的 XAML 中分配的 Click 事件 就像常规按钮一样 当它被单击时 我想执行 Click 事件处理程序 如果已分配 否则我想执行默
  • 每个租户的唯一用户名和电子邮件

    我正在使用以下代码编写多租户应用程序ASP NET Core 2 1 我想覆盖默认的与用户创建相关的验证机制 目前我无法创建多个具有相同的用户UserName My ApplicationUser模型有一个名为TenantID 我想要实现的
  • .NET Core 中的跨平台文件名处理

    如何处理文件名System IO以跨平台方式运行类以使其在 Windows 和 Linux 上运行 例如 我编写的代码在 Windows 上完美运行 但它不会在 Ubuntu Linux 上创建文件 var tempFilename Dat
  • 我可以让 ungetc 取消阻止阻塞的 fgetc 调用吗?

    我想在收到 SIGUSR1 后使用 ungetc 将 A 字符重新填充到标准输入中 想象一下我有充分的理由这样做 调用 foo 时 stdin 中的阻塞读取不会被收到信号时的 ungetc 调用中断 虽然我没想到它会按原样工作 但我想知道是
  • cout 和字符串连接

    我刚刚复习了我的 C 我尝试这样做 include
  • C++ Streambuf 方法可以抛出异常吗?

    我正在尝试找到一种方法来获取读取或写入流的字符数 即使存在错误并且读 写结束时间较短 该方法也是可靠的 我正在做这样的事情 return stream rdbuf gt sputn buffer buffer size 但如果streamb

随机推荐

  • 程序员搜索技巧

    1 搜索时 一定使用关键字搜索 空格 浓缩减少废话与口语 不断负反馈增添修改关键词 再不行就英文 2 精确搜索 作为整体 用 双引号 3 查找标题含有的确定关键词 intitle 英文冒号 4 站内搜索 过滤垃圾广告 定位某一网址答案 xx
  • Cobertura 统计多模块maven项目测试覆盖率

    Cobertura 统计单元测试覆盖率的机制 运行类 并在一个log文件中记录哪一行被执行 然后将源代码和log文件进行比对 1 简单的情况 单模块maven项目 项目结构 源代码 src main java se sigma calcul
  • OpenCV图像人脸检测及视频中的人脸检测(附源码)

    文章目录 一 数据和知识准备 1 下载HAAR与LBP数据 2 opencv相关知识 二 python opencv实现人脸检测 1 图像单人脸检测 2 图像多人脸检测 3 视频中人脸检测 4 摄像头人脸检测 一 数据和知识准备 1 下载H
  • java中的垃圾回收机制

    概述 JAVA中的垃圾回收机制是自动的 它是保证程序健壮的主要手段 同时也避免了回收内存带来的代码繁琐 注意 1 java中的垃圾回收机制采用的是多线程技术实现的 垃圾回收功能是一条优先级比较低的线程 2 垃圾回收机制仅仅作用于堆内存 和栈
  • Unity一些很有用的技巧

    一 性能 多线程射线检测 在使用中经常需要每帧进行射线 性能消耗比较大 那么可以使用Unity Collections RaycastCommand进行多线程的检查 将耗能操作放到子线程去 同样其他的形状检测 Unity官方文档 Rayca
  • Python每日一记196>>>pandas.core.indexing.IndexingError: Too many indexers

    以下代码出现了pandas core indexing IndexingError Too many indexers问题 import pandas as pd import numpy as np data 2018 pd read e
  • Rust组合器

    组合器 在 Rust 中 组合器更多的是用于对返回结果的类型进行变换 例如使用 ok or 将一个 Option 类型转换成 Result 类型 下面我们来看看一些常见的组合器 or 和 and 跟布尔关系的与 或很像 这两个方法会对两个表
  • JAVA 8 junit 单元测试——静态方法单元测试 Mockito.mockStatic

    静态方法的单元测试Mockito 直接上例子 方法 public ArrayList
  • 深度缓冲详解(DepthBuffer)

    参考出处 1 OpenGL 深度缓冲区 Z缓冲区 介绍 2 什么是深度缓冲 Depth Buffer 1 深度缓冲概念 深度缓冲区与帧缓冲区相对应 用于记录上面每个像素的深度值 通过深度缓冲区 我们可以进行深度测试 从而确定像素的遮挡关系
  • VMware安装流畅系统Chrome OS以及国产系统FedyOS(基于Chrome OS的二次开发)

    一 序言 VMware 版本 15 5 6 物理机型号 芯片类型不限制 不向之前发布的vmware安装Mac OS篇 想看的点击这 二 链接资源 Chrome OS CloudReady Home v83 x64 点击进入 提取码 yyds
  • linux与线程

    1 1 1 进程 在早期 人们都是为特定机器编写程序 并在其上运行计算任务 task 渐渐的人们发现CPU与IO设备之间速度差太多了 往往CPU都在空转 是不是可以在CPU空闲的时候做些其他事呢 于是 就有了多任务 每个任务就是一个进程 有
  • excel wind插件使用_Python和wind的交互—在债券中的应用

    个人认为学会了怎么用python和wind交互以及怎么用python处理Excel数据 就基本能替换日常很多琐碎的债券工作 还不用担心Excel某个值改变了导致整个报表都毁了 事实上在python调用wind函数和在Excel中调用函数一样
  • Lua: string字符串的处理

    目录 1 字符串的三种表示方式 2 字符串操作 3 特别说一下 dump序列化Lua 函数 1 字符串的三种表示方式 lua 字符串的三种表示 单引号字符串 string a hello world print string a 双引号字符
  • Selenium控制已打开的chrome、IE浏览器

    0 为什么要接管打开的浏览器 1 重复重新登录 过程麻烦 2 拖慢爬虫的运行速度 3 容易让网站检测到账号异常 如何解决重复登录的问题 1 使用登录过的cookie 下次运行时设置保存 2 接管打开的浏览器 也是我们接下来重点讲的 1 控制
  • 9.Markdown 高级技巧(内嵌HTML+公式+对齐方式)

    支持的 HTML 元素 CSDN支持kbd标签 有道云目前不支持 使用
  • Java基础面试题

    1 面向对象的特征有哪些方面 1 抽象 抽象就是忽略一个主题中与当前目标无关的那些方面 以便更充分地注意与当前目标有关的方面 抽象并不打算了解全部问题 而只是选择其中的一部分 暂时不用部分细节 抽象包括两个方面 一是过程抽象 二是数据抽象
  • 十分钟让你明白Objective-C的语法(和Java、C++的对比)

    很多想开发iOS 或者正在开发iOS的程序员以前都做过Java或者C 当第一次看到Objective C的代码时都会头疼 Objective C的代码在语法上和Java C 有着很大的区别 有的同学会感觉像是看天书一样 不过 语言都是相通的
  • smp和mpp计算机

    SMP 是Symmetric Multi Processing的简称 意为对称多处理系统 内有许多紧耦合多处理器 这种系统的最 大特点就是共享所有资源 MPP 另外与之相对立的标准是MPP Massively Parallel Proces
  • Linux驱动

    Linux驱动入门系列 Linux驱动入门 一 字符设备驱动基础 Linux驱动入门 二 操作硬件 Linux驱动入门 三 Led驱动 Linux驱动入门 四 非阻塞方式实现按键驱动 Linux驱动入门 五 阻塞方式实现按键驱动 Linux
  • ​7.1 项目1 学生通讯录管理:文本文件增删改查(C++版本)(自顶向下设计+断点调试) (A)​

    C 自学精简教程 目录 必读 作业目标 这个作业中 你需要综合运用之前文章中的知识 来解决一个相对完整的应用程序 作业描述 1 在这个作业中你需要在文本文件中存储学生通讯录的信息 并在程序启动的时候加载这些数据到内存中 2 在程序运行过程中