求大佬修改代码,优化重复度和添加另外功能.
// ConsoleApplication1.cpp: 定义控制台应用程序的入口点。//
#include "stdafx.h"
#pragma warning(disable:4996)
#include<stdio.h>
#include <stdlib.h>
#include <windows.h>
#include<fstream>
#include<iostream>
#include<string>
using namespace std;
#define MAXSIZE 20 //电话薄记录数量
#define MAX_SIZE 18 //人名的最大长度
#define HASHSIZE 90 //定义表长
#define SUCCESS 1
#define UNSUCCESS -1
#define LEN sizeof(HashTable) //为建立的对象定义长度
typedef int Status; //为现有类型添加一个同义字
typedef char NA[MAX_SIZE]; // typedef 掩饰数组类型
static int m = 0;
typedef struct people //记录
{
NA name;
NA tel; //关键字
NA add;
}Record; //查找表中记录类型
typedef struct //建立哈希表
{
Record *elem[HASHSIZE]; //数据元素存储基址
int count; //当前数据元素个数
int size; //当前容量
}HashTable;
int i;
void Menu()
{
printf(" ######################################################################n");
printf(" # ttt 通讯录查找系统 #n");
printf(" ## ttt ―――――― ttt ##n");
printf(" # ttt 【 1.创建 】 # n");
printf(" # ttt ―――――― #n");
printf(" # ttt 【 2.写入 】 #n");
printf(" # ttt ―――――― #n");
printf(" # ttt 【 3.建表 】 #n");
printf(" # ttt ―――――― #n");
printf(" # ttt 【 4.查找 】 #n");
printf(" # ttt ―――――― #n");
printf(" # ttt 【 5.删除 】 #n");
printf(" # ttt ―――――― #n");
printf(" # ttt 【 6.修改 】 #n");
printf(" # ttt ―――――― #n");
printf(" # ttt 【 7.查看 】 #n");
printf(" # ttt ―――――― #n");
printf(" # ttt 【 8.保存 】 #n");
printf(" # ttt ―――――― #n");
printf(" # ttt 【 9.读取 】 #n");
printf(" # ttt ―――――― #n");
printf(" # ttt 【 0.退出 】 #n");
printf(" ## ttt ―――――― ##n");
printf(" ######################################################################n");
}
void benGetTime() //建立时间函数
{
SYSTEMTIME sys;
GetLocalTime(&sys);
printf("%4d/%02d/%02d %02d:%02d:%02d.%03d n", sys.wYear, sys.wMonth, sys.wDay, sys.wHour, sys.wMinute, sys.wSecond, sys.wMilliseconds);
}
Status NUM_BER; //记录的个数
Status NUM_BER1;
void Create(Record* a) //创建新的通讯录
{
system("CLS"); //调用DOS命令CLS能够清屏
FILE *fp1, *fp2;
if ((fp1 = fopen("record.txt", "r")) != NULL) //打开文件
{
fclose(fp1); //关闭文件
}
else
{
fp2 = fopen("record.txt", "w"); //如果不存在record.txt就创建一个
fclose(fp2);
}
printf("n");
printf("#############################################################n");
printf("==================== → 创建成功 ← ===================n");
printf("#############################################################n");
printf("n");
printf("◇◆请按ENTER进入添加通讯信息菜单◇◆n");
getchar();
system("CLS");
system("CLS"); //调用DOS命令CLS能够清屏
printf("#############################################################n");
printf("==================== → 用户信息记录表 ← ===================n");
printf("#############################################################n");
printf("输入要添加的个数:n");
scanf("%d", &NUM_BER);
for (i = 0; i<NUM_BER; i++)
{
printf("请输入第%d个记录的用户名:n", i + 1);
scanf("%s", a[i].name);
printf("请输入%d个记录的电话号码:n", i + 1);
scanf("%s", a[i].tel);
printf("请输入第%d个记录的地址:n", i + 1);
scanf("%s", a[i].add);
}
getchar();
printf("####################################n");
printf("添加成功!!!n");
benGetTime();
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~n");
printf("◇◆请按ENTER返回功能操作菜单◇◆n");
printf("####################################n");
getchar();
}
Status eq(NA x, NA y) //关键字比较,相等返回SUCCESS;否则返回UNSUCCESS
{
if (strcmp(x, y) == 0)
{
return SUCCESS;
}
else return UNSUCCESS;
}
void Append(Record* a) //键盘输入各人的信息
{
system("CLS"); //调用DOS命令CLS能够清屏
printf("#############################################################n");
printf("==================== → 用户信息记录表 ← ===================n");
printf("#############################################################n");
printf("输入要添加的个数:n");
scanf("%d", &NUM_BER1);
int j = i;
for (i; i<j + NUM_BER1; i++)
{
printf("请输入第%d个记录的用户名:n", i + 1);
scanf("%s", a[i].name);
printf("请输入%d个记录的电话号码:n", i + 1);
scanf("%s", a[i].tel);
printf("请输入第%d个记录的地址:n", i + 1);
scanf("%s", a[i].add);
}
getchar();
printf("####################################n");
printf("添加成功!!!n");
benGetTime();
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~n");
printf("◇◆请按ENTER返回功能操作菜单◇◆n");
printf("####################################n");
getchar();
}
void List(Record* a) //显示通讯录中所有记录
{
Record *p;
p = a;
int i;
system("CLS"); //调用DOS命令CLS能够清屏
printf("#############################################################n");
printf("==================== → 用户信息记录表 ← ===================n");
printf("#############################################################n");
if (a != NULL)
{
printf("nn姓名t电话号tt地址n");
printf("_____________________________________________________n");
for (i = 0; i<NUM_BER + NUM_BER1 - m; i++)
{
printf("%st%stt%sn", a[i].name, a[i].tel, a[i].add);
printf("_____________________________________________________n");
}
}
else
{
printf("对不起!!没有任何联系人记录!!nn");
printf("=============================================================n");
}
benGetTime();
printf("#################################n");
printf("◇◆请按ENTER返回功能操作菜单◇◆n");
printf("#################################n");
getchar();
}
int Hash(NA str) //哈希函数
{
system("CLS"); //调用DOS命令CLS能够清屏
long n;
int m;
n = atoi(str); //把字符串转换成整型数.
m = n%HASHSIZE; //用除留余数法构造哈希函数
return m; //并返回模值
}
Status collision(int p, int &c) //冲突处理函数,采用二次探测再散列法解决冲突
{
int i, q;
i = c / 2 + 1;
while (i<HASHSIZE)
{
if (c % 2 == 0)
{
c++;
q = (p + i*i) % HASHSIZE;
if (q >= 0)
{
return q;
}
else
{
i = c / 2 + 1;
}
}
else
{
q = (p - i*i) % HASHSIZE;
c++;
if (q >= 0)
{
return q;
}
else
{
i = c / 2 + 1;
}
}
}
return UNSUCCESS;
}
void CreateHash(HashTable* H, Record* a) //建表,以电话号码为关键字,建立相应的散列表
{
system("CLS"); //调用DOS命令CLS能够清屏
int i, p = -1, c, pp;
for (i = 0; i<NUM_BER + NUM_BER1; i++)
{
c = 0;
p = Hash(a[i].tel);
pp = p;
while (H->elem[pp] != NULL)
{
pp = collision(p, c); //若哈希地址冲突,进行冲突处理
if (pp<0)
{
printf("#############################################################n");
printf("==================== → 用户信息记录表 ← ===================n");
printf("#############################################################n");
printf("第%d记录无法解决冲突", i + 1); //需要显示冲突次数时输出
continue;
} //无法解决冲突,跳入下一循环
}
H->elem[pp] = &(a[i]); //求得哈希地址,将信息存入
H->count++;
printf("#############################################################n");
printf("==================== → 用户信息记录表 ← ===================n");
printf("#############################################################n");
printf("第%d个记录冲突次数为%d。n", i + 1, c); //需要显示冲突次数时输出
}
printf("n建表完成!n此哈希表容量为%d,当前表内存储的记录个数为%d.n", HASHSIZE, H->count);
benGetTime();
printf("#################################n");
printf("◇◆请按ENTER返回功能操作菜单◇◆n");
printf("#################################n");
getchar();
}
void Find(HashTable* H, int &c) //在通讯录里查找电话号码关键字,若查找成功,显示信息
{
system("CLS"); //调用DOS命令CLS能够清屏
printf("#############################################################n");
printf("==================== → 用户信息记录表 ← ===================n");
printf("#############################################################n");
benGetTime();
NA tele;
printf("n请输入要查找记录的电话号码:n");
scanf("%s", tele);
int p, pp;
p = Hash(tele);
pp = p;
while ((H->elem[pp] != NULL) && (eq(tele, H->elem[pp]->tel) == -1))
pp = collision(p, c);
if (H->elem[pp] != NULL&&eq(tele, H->elem[pp]->tel) == 1)
{
printf("#############################################################n");
printf("==================== → 用户信息记录表 ← ===================n");
printf("#############################################################n");
printf("n查找成功!n查找过程冲突次数为%d.以下是您需要要查找的信息:nn", c);
// printf("姓 名:%sn电话号码:%sn联系地址:%sn",H->elem[pp]->name,H->elem[pp]->tel,H->elem[pp]->add);
printf("nn姓名t电话号tt地址n");
printf("_____________________________________________________n");
printf("%st%stt%sn", H->elem[pp]->name, H->elem[pp]->tel, H->elem[pp]->add);
printf("_____________________________________________________n");
}
else
printf("n此人不存在,查找不成功!n");
benGetTime();
getchar();
printf("#################################n");
printf("◇◆请按ENTER返回功能操作菜单◇◆n");
printf("#################################n");
getchar();
}
void Alter(HashTable* H, int &c) //在通讯录里修改某人信息
{
system("CLS"); //调用DOS命令CLS能够清屏
printf("#############################################################n");
printf("==================== → 用户信息记录表 ← ===================n");
printf("#############################################################n");
benGetTime();
NA tele;
printf("n请输入要修改记录的电话号码:n");
scanf("%s", tele);
int p, pp;
p = Hash(tele);
pp = p;
while ((H->elem[pp] != NULL) && (eq(tele, H->elem[pp]->tel) == -1))
pp = collision(p, c);
if (H->elem[pp] != NULL&&eq(tele, H->elem[pp]->tel) == 1)
{
printf("#############################################################n");
printf("==================== → 用户信息记录表 ← ===================n");
printf("#############################################################n");
printf("n以下是您需要修改的信息:");
printf("n");
printf("nn姓名t电话号tt地址n");
printf("_____________________________________________________n");
printf("%st%stt%sn", H->elem[pp]->name, H->elem[pp]->tel, H->elem[pp]->add);
printf("_____________________________________________________n");
(H->elem)[pp]->tel[0] = '�';
printf("请输入修改后记录的用户名:n");
scanf("%s", H->elem[pp]->name);
printf("请输入修改后记录的电话号码:n");
scanf("%s", H->elem[pp]->tel);
printf("请输入修改后记录的地址:n");
scanf("%s", H->elem[pp]->add);
printf("修改成功!!!");
}
else
{
printf("#############################################################n");
printf("==================== → 用户信息记录表 ← ===================n");
printf("#############################################################n");
benGetTime();
printf("n此人不存在,修改不成功!n");
}
getchar();
printf("#################################n");
printf("◇◆请按ENTER返回功能操作菜单◇◆n");
printf("#################################n");
getchar();
}
void Delete(HashTable* H, int &c) //在通讯录里查找电话号码关键字,若查找成功,显示信息然后删除
{
system("CLS"); //调用DOS命令CLS能够清屏
printf("#############################################################n");
printf("==================== → 用户信息记录表 ← ===================n");
printf("#############################################################n");
benGetTime();
NA tele;
printf("n请输入要删除记录的电话号码:n");
m++;
scanf("%s", tele);
int p, pp;
p = Hash(tele);
pp = p;
while ((H->elem[pp] != NULL) && (eq(tele, H->elem[pp]->tel) == -1))
pp = collision(p, c);
if (H->elem[pp] != NULL&&eq(tele, H->elem[pp]->tel) == 1)
{
printf("#############################################################n");
printf("==================== → 用户信息记录表 ← ===================n");
printf("#############################################################n");
printf("n以下是您需要要删除的信息:nn", c);
printf("nn姓名t电话号tt地址n");
printf("_____________________________________________________n");
printf("%st%stt%sn", H->elem[pp]->name, H->elem[pp]->tel, H->elem[pp]->add);
printf("_____________________________________________________n");
printf("n");
(H->elem)[pp]->tel[0] = '�';
printf("删除成功!!!");
}
else
printf("n此人不存在,删除不成功!n");
benGetTime();
getchar();
printf("#################################n");
printf("◇◆请按ENTER返回功能操作菜单◇◆n");
printf("#################################n");
getchar();
}
void Save(HashTable * H) //将记录保存到指定文件
{
system("CLS");
FILE* fp;
if ((fp = fopen("record.txt", "w")) != NULL)
{
fprintf(fp, "#############################################################n");
fprintf(fp, "==================== → 用户信息记录表 ← ===================n");
fprintf(fp, "#############################################################n");
for (int i = 0; i<HASHSIZE; i++)
{
if ((H->elem)[i] != '�')
{
fprintf(fp, "====================================================n");
fprintf(fp, "联系人姓名:%sn", H->elem[i]->name);
fprintf(fp, "联系人电话:%sn", H->elem[i]->tel);
fprintf(fp, "联系人地址:%sn", H->elem[i]->add);
fprintf(fp, "====================================================n");
}
}
fclose(fp);
printf("#############################################################n");
printf("==================== → 用户信息记录表 ← ===================n");
printf("#############################################################n");
benGetTime();
printf("nn恭喜你!!成功储存,你能在record.txt找到相应纪录n");
printf("#############################################################n");
system("pause");
}
else
{
benGetTime();
printf("抱歉,保存记录失败!!");
system("pause");
}
}
void Load()
{
system("CLS");
ifstream inFile;
inFile.open("record.txt"); // 打开文件
string str; // 行字符串缓存
if (inFile.is_open()) // 若成功打开文件
{
while (!inFile.eof()) // 若未到文件结束
{
getline(inFile, str, 'n'); // 读取一行内容,并存入缓存str中,'n'表示一行结束的回车符
cout << str << endl; // 把缓存内容输出到屏幕
}
}
inFile.close();
printf("#################################n");
printf("◇◆请按ENTER返回功能操作菜单◇◆n");
printf("#################################n");
getchar();
}
void Quit() //结束
{
system("cls");
system("color F0");
printf("########################################################n");
printf("☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★n");
printf(" 谢谢使用! 再见!!!n");
printf("☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★n");
printf(" 祝你 n");
printf("☆幸福快乐☆ ☆生活愉快☆ ☆吉祥如意☆ ☆合家欢乐☆n");
printf("########################################################n");
}
int main(int argc, char* argv[])
{
system("color F0");
system("CLS"); //调用DOS命令CLS能够清屏
int c, flag = 1;
HashTable *H;
H = (HashTable*)malloc(LEN);
for (int i = 0; i<HASHSIZE; i++)
H->elem[i] = NULL;
H->size = HASHSIZE;
H->count = 0;
Record a[MAXSIZE];
int i = 0;
int pwd, key = 123456;//key为假设密码
printf(" ######################################n");
cout << " ##为了保证数据安全,请输入密码后使用##" << endl;
cout << " ##为了保证数据安全,请输入密码后使用##" << endl;
printf(" ######################################n");
printf("n");
printf("n");
printf("n");
do
{
if (i != 0)
cout << "密码错误!" << endl;
cout << "第 " << i + 1 << " 次输入密码: ";
cin >> pwd;
system("color F0");
system("CLS");
} while (pwd != key&&++i<3);
if (i == 3)
{
cout << "密码错误,3次机会已经用完!n拒绝使用通讯录管理系统!" << endl;
}
else
{
cout << "☆★☆★☆★☆★☆★☆★☆★☆" << endl;
cout << " 欢迎使用通讯录管理系统" << endl;
cout << "☆★☆★☆★☆★☆★☆★☆★☆" << endl;
benGetTime();
printf("n");
getchar();
printf("请按ENTER进入功能操作菜单n");
getchar();
system("CLS");
while (1)
{
Menu();
printf("请输入一个任务选项>>>");
int num;
scanf("%d", &num); getchar();
switch (num) {
case 1:Create(a); break;
case 2:Append(a); break;
case 3:CreateHash(H, a); break;
case 4:c = 0; Find(H, c); break;
case 5:c = 0; Delete(H, c); break;
case 6:c = 0; Alter(H, c); break;
case 7:List(a); break;
case 8:Save(H); break;
case 9:Load(); break;
case 0:Quit(); return 0; break;
case 10:;; break;
default:
printf("你输错了,请重新输入!");
printf("n");
}
system("CLS");
}
return 0;
}
}