用线性表实现通讯录管理
功能6有很大问题,实现不了功能,有时能输出,但只能输出一条信息(多条信息符合条件时);当无符合条件的信息时,没有输出相应信息
此外,地址输出字数不一时,表格对不齐,请问有什么改进的办法
万分感谢
//题目3——应用实验
#include
using namespace std;
#include
#define MAX 50
#include
#include
void menu()//展示菜单栏
{
cout << "--------------------------------------" << endl;
cout << "------------通讯录管理系统------------" << endl;
cout << "------------1.添加联系人--------------" << endl;
cout << "------------2.删除联系人--------------" << endl;
cout << "------------3.查找联系人--------------" << endl;
cout << "------------4.更改联系人信息----------" << endl;
cout << "------------5.显示通讯录--------------" << endl;
cout << "------------6.按分类显示通讯录--------" << endl;
cout << "------------0.退出通讯录--------------" << endl;
cout << "--------------------------------------" << endl;
}
struct DataType//通讯录要存储的信息
{
int ID;//编号
string name;//姓名
string ch;//性别
string phone;//电话
string addr;//地址
string classify;//分类
};
struct Data_s
{
struct DataType people[MAX];//通讯录能保存的最大人数
int length = 0;//通讯录中已有人数
};
void Assign(Data_s* Ds)
{
int ID_;//ID
cout << "请输入联系人ID:";
cin >> ID_;
Ds->people[Ds->length].ID = ID_;
string name_;//姓名
cout << "请输入联系人姓名:";
cin >> name_;
Ds->people[Ds->length].name = name_;
string ch_;//性别
cout << "请输入联系人性别:";
cin >> ch_;
Ds->people[Ds->length].ch = ch_;
string phone_;//电话
cout << "请输入联系人电话号码:";
cin >> phone_;
Ds->people[Ds->length].phone = phone_;
string addr_;//地址
cout << "请输入联系人地址:";
cin >> addr_;
Ds->people[Ds->length].addr = addr_;
int cla;//分类
cout << "请输入联系人分类(1——好友;2——同学;3——黑名单):";
while (true)
{
cin >> cla;
if (cla == 1 || cla == 2 || cla == 3)
{
if (cla == 1)
Ds->people[Ds->length].classify = "好友";
if (cla == 2)
Ds->people[Ds->length].classify = "同学";
if (cla == 3)
Ds->people[Ds->length].classify = "黑名单";
}
break;
}
}
void Assign(Data_s* Ds, int num)
{
int ID_;//ID
cout << "请输入联系人ID:";
cin >> ID_;
Ds->people[num].ID = ID_;
string name_;//姓名
cout << "请输入联系人姓名:";
cin >> name_;
Ds->people[num].name = name_;
string ch_;//性别
cout << "请输入联系人性别:";
cin >> ch_;
Ds->people[num].ch = ch_;
string phone_;//电话
cout << "请输入联系人电话号码:";
cin >> phone_;
Ds->people[num].phone = phone_;
string addr_;//地址
cout << "请输入联系人地址:";
cin >> addr_;
Ds->people[num].addr = addr_;
int cla;//分类
cout << "请输入联系人分类(1——好友;2——同学;3——黑名单):";
while (true)
{
cin >> cla;
if (cla == 1 || cla == 2 || cla == 3)
{
if (cla == 1)
Ds->people[num].classify = "好友";
if (cla == 2)
Ds->people[num].classify = "同学";
if (cla == 3)
Ds->people[num].classify = "黑名单";
}
}
}
void ADD(Data_s* Ds)
{
//首先判断通讯录是否已满
if (Ds->length == MAX)
cout << "通讯录已满" << endl;
cout << "请根据提示输入联系人相关信息" << endl;
Assign(Ds);
Ds->length++;
cout << "新联系人已添加成功!" << endl;
system("pause");
system("cls");//清屏
}
vector<int> existance(Data_s* Ds, int cla)//根据分类查找联系人是否存在,若存在,返回该联系人所属下标
{
string cla_;
if (cla == 1)
cla_ = "好友";
else if (cla == 2)
cla_ = "同学";
else if (cla == 3)
cla_ = "黑名单";
vector<int>v3;
for (int j = 0; j < Ds->length; j++)
{
vector<int>v2;
int k = 0;
if (Ds->people[j].classify == cla_)
{
v2.push_back(j);
k++;
}
return v2;
}
return v3;//查找失败
}
int existance(Data_s* Ds, string name)//根据姓名查找联系人是否存在,若存在,返回该联系人所属下标
{
for (int i = 0; i < Ds->length; i++)
{
if (Ds->people[i].name == name)
return i;
}
return -1;//查找失败
}
void ShowLine()
{
int j;
for (j = 0; j < 44; j++)
{
cout << "——";
}
cout << endl;
}
void DELETE(Data_s* Ds, int num)
{
DataType ds = Ds->people[num];
for (int i = 0; i < Ds->length - 1; i++)
Ds->people[i] = Ds->people[i + 1];
Ds->length--;
}
void ShowHeading()
{
//打印标题
ShowLine();
cout << "|\t\t\t\t\t" << "通讯录" << setw(40) << "\t\t\t\t\t\t|" << endl;
ShowLine();
cout << "|ID\t\t" << "|姓名\t" << "|性别\t"<< "|电话\t\t\t" << "|地址\t\t\t"<< "|分类\t" <<"|" << endl;
ShowLine();
}
void SHOW(Data_s* Ds)
{
if (Ds->length == 0)
{
cout << "通讯录为空,请添加联系人!" << endl;
system("pause");
system("cls");
return;
}
//打印标题
ShowHeading();
//输出内容
for (int i = 0; i < Ds->length; i++)
{
cout << "|" << Ds->people[i].ID << "\t\t|" << Ds->people[i].name << "\t|" << Ds->people[i].ch << "\t|" << Ds->people[i].phone
<< "\t\t|" << Ds->people[i].addr << "\t\t|" << Ds->people[i].classify << "\t|" << endl;
ShowLine();
}
system("pause");
system("cls");
}
void SHOW(Data_s* Ds, int cla)
{
if (cla)
{
cout << "该分类通讯录为空" << endl;
return;
}
//输出内容
cout << "|" << Ds->people[cla].ID << "\t\t|" << Ds->people[cla].name << "\t|" << Ds->people[cla].ch << "\t|"
<< Ds->people[cla].phone << "\t\t|" << Ds->people[cla].addr << "\t\t|" << Ds->people[cla].classify << "\t|" << endl;
ShowLine();
}
int main()
{
Data_s Ds;//创建通讯录
Ds.length = 0;
while (true)
{
int select = 0;//用户选择输入的数字
menu();//展示菜单栏
cin >> select;
switch (select)
{
case 1://添加联系人ADD
ADD(&Ds);
break;
case 2://删除联系人DELETE
{
cout << "请输入要删除的联系人姓名";
string name;
cin >> name;
int num;
num = existance(&Ds, name);
if (num == -1)
{
cout << "您要删除的联系人不存在" << endl;
}
else
{
DELETE(&Ds, num);
cout << name << "已被移除通讯录" << endl;
}
system("pause");
system("cls");
}
break;
case 3://查找联系人
{
cout << "请输入要查找的联系人姓名:";
string name;
cin >> name;
int num;
num = existance(&Ds, name);
if (num == -1)
{
cout << "您所查找的联系人不存在" << endl;
}
else
{
ShowHeading();
cout << "|" << Ds.people[num].ID<< "\t\t|" << Ds.people[num].name <<"\t|"<< Ds.people[num].ch <<"\t|" << Ds.people[num].phone
<< "\t\t|" << Ds.people[num].addr<<"\t\t|" << Ds.people[num].classify << "\t|" << endl;
ShowLine();
}
system("pause");
system("cls");
}
break;
case 4://更改通讯录ALTER
{
cout << "请输入要更改信息的联系人姓名:";
string name;
cin >> name;
int num;
num = existance(&Ds, name);
if (num == -1)
cout << "您所查找的联系人不存在" << endl;
else
{
Assign(&Ds, num);
cout << "已更改成功!" << endl;
}
system("pause");
system("cls");
}
break;
case 5://显示通讯录SHOW
SHOW(&Ds);
break;
case 6://按分类显示通讯录SHOW的重载
{
cout << "请输入想要显示的分类(1——好友;2——同学;3——黑名单):";
int cla;
cin >> cla;
vector<int>v;
v = existance(&Ds, cla);
for (int i = 0; i < v.capacity(); i++)
{
ShowHeading();
while ((v[i] + 1) != 0)
{
SHOW(&Ds, v[i]);
break;
}
system("pause");
system("cls");
}
}
break;
case 0://退出通讯录EXIT
cout << "您已退出通讯录" << endl;
system("pause");
return 0;
break;
}
}
return 0;
}
该回答引用于gpt与OKX安生共同编写:
您的代码,我看到您在实现功能6时遇到问题。从您提供的代码来看,问题主要在于existace函数返回值的处理上。
在existace函数中,当查找成功时,您只返回了第一个匹配的位置,并没有考虑到可能有多个匹配的情况。因此,在调用existace函数时,只能得到第一个匹配的结果。
为了解决这个问题,您可以使用vector或者其他容器来存储所有匹配的位置,然后在根据这些位置输出所有符合条件的联系人信息。
另外,关于地址输出字数不一和表格对齐问题,您可以考虑使用setw函数设置每一列的宽度,以使输出的表格对齐。例如:
cout << "|ID\t" << "|姓名\t" << "|性别\t"<< "|电话\t\t\t" << "|地址\t\t\t"<< "|分类\t" <<"|" << endl;
ShowLine();
for (int i = 0; i < Ds->length; i++)
{
cout << "|" << setw(2) << Ds->people[i].ID << "\t"
<< "|" << setw(4) << Ds->people[i].name << "\t"
<< "|" << setw(4) << Ds->people[i].ch << "\t"
<< "|" << setw(17) << Ds->people[i].phone << "\t"
<< "|" << setw(17) << Ds->people[i].addr << "\t"
<< "|" << setw(5) << Ds->people[i].classify << "\t" <<"|" << endl;
ShowLine();
}
希望这些提示能够帮助您解决问题。
你的代码我不是很理解,我按照自己的想法把existance函数、show函数、还有main里面的case 6改了一下,这是运行结果:
vector<int>& existance(Data_s* Ds, int cla) { //根据分类查找联系人是否存在,若存在,返回该联系人所属下标
static vector<int> v;
v.clear();
string cla_[] = {"好友", "同学", "黑名单"};
for (int j = 0; j < Ds->length; j++) {
int k = 0;
if (Ds->people[j].classify == cla_[cla - 1]) {
v.push_back(j);
k++;
}
}
return v;//查找失败
}
这是修改后show函数:
void SHOW(Data_s * Ds, int n) {
//输出内容
cout << setiosflags(ios::left) << "|" << setw(10) << Ds->people[n].ID << "\t|" << setw(7) << Ds->people[n].name << "|" << setw(3) << Ds->people[n].ch << "\t|" << setw(18) << Ds->people[n].phone
<< "\t|" << setw(18) << Ds->people[n].addr << "\t|" << Ds->people[n].classify << "\t|" << endl;
ShowLine();
}
这是修改后的case 6:
case 6: { //按分类显示通讯录SHOW的重载
cout << "请输入想要显示的分类(1——好友;2——同学;3——黑名单):";
int cla;
cin >> cla;
vector<int>&v = existance(&Ds, cla);
if (v.empty())cout << "该分类通讯录为空" << endl;
else ShowHeading();
for (int i = 0; i < (int)v.size(); i++) {
SHOW(&Ds, v[i]);
}
system("pause");
system("cls");
}
定长输出可以用setw函数,如:
cout<<setw(10)<<str<<endl;
修改后的SHOW函数:
void SHOW(Data_s* Ds) {
if (Ds->length == 0) {
cout << "通讯录为空,请添加联系人!" << endl;
system("pause");
system("cls");
return;
}
//打印标题
ShowHeading();
//输出内容
for (int i = 0; i < Ds->length; i++) {
cout << setiosflags(ios::left) << "|" << setw(10) << Ds->people[i].ID << "\t|" << setw(7)<< Ds->people[i].name << "|"<< setw(3)<< Ds->people[i].ch << "\t|" <<setw(18) << Ds->people[i].phone
<< "\t|"<<setw(18) << Ds->people[i].addr << "\t|" << Ds->people[i].classify << "\t|" << endl;
ShowLine();
}
system("pause");
system("cls");
}
参考GPT和自己的思路:针对问题6的输出问题,可以考虑使用循环遍历整个通讯录,将符合条件的联系人信息存储到一个容器中,再将容器中的信息输出,这样可以解决只能输出一条信息的问题。同时,可以在输出地址时使用字符对齐函数,如setw函数,可以控制每个字段的宽度,使表格更加整齐美观。
从逻辑上说
if (Ds->length == MAX)
{
cout << "通讯录已满" << endl;
return; //这里应该 returnの而不是继续执行
}
...
Assign 函数中的分类输入部分也有问题,应该将 break 移到 if 语句里面,否则无论输入的分类是否正确都会结束循环。
以下答案由GPT-3.5大模型与博主波罗歌共同编写:
代码中存在几个问题,下面逐一分析:
if (Ds->length == MAX)
中没有加入花括号,导致下一行的代码会执行循环体内的操作。
int cla
输入分类后没有进行错误判断,如果输入的分类不在[1,3]范围内,会出现错误。
existance
函数中有多处问题。首先,应该在找到符合条件的联系人后将其下标存入一个 vector 中,而不是仅存入一个 int 变量中。其次,return v2
应该在 for 循环结束后进行,当无符合条件的联系人时应该返回空的 vector。最后,函数返回类型的声明应该从 int 改为 vector。
SHOW
函数中输出的字段,比如 ID、姓名、性别等,应该保持一致的长度,可以使用 setw()
函数控制宽度。
DELETE
函数中,删除联系人后应该将最后一个联系人移动到删除的位置,而不是将被删除的联系人后面的所有联系人依次移动一个位置。
下面是修改后的代码:
如果我的回答解决了您的问题,请采纳!