需求分析:
1.添加联系人
2.通过关键字查询
3.查看所有联系人 和详细信息
4.删除联系人
5.排序
系统设计:
1.结构体保存联系人信息.
2 结构体数组存储多个联系人
3 文件保存数据 提高效率
宏定义: FOMAT 格式化输出 DATA 对结构体中所有成员的引用
知识点:
1. C++ I/O 标准库详解
C++输入输出的概念:
从操作系统的角度看,每一个与主机相连的输入输出设备都被看作一个文件。
程序的输入指的是从输入文件将数据传送给程序,程序的输出指的是从程序将数据传送给输出文件。
C++输入输出包含以下三个方面的内容:
-
对系统指定的标准设备的输入和输出。即从键盘输入数据,输出到显示器屏幕。这种输入输出称为标准的输入输出,简称标准I/O。
-
以外存磁盘文件为对象进行输入和输出,即从磁盘文件输入数据,数据输出到磁盘文件。以外存文件为对象的输入输出称为文件的输入输出,简称文件I/O。
-
对内存中指定的空间进行输入和输出。通常指定一个字符数组作为存储空间(实际上可以利用该空间存储任何信息)。这种输入和输出称为字符串输入输出,简称串I/O。
在C++的输入输出中,编译系统对数据类型进行严格的检查,凡是类型不正确的数据都不可能通过编译。因此C++的I/O操作是类型安全(type safe)的。
可扩展性是C++输人输出的重要特点之一,它能提高软件的重用性,加快软件的开 发过程。
C++通过I/O类库来实现丰富的I/O功能。
输入和输出是数据传送的过程,数据如流水一样从一处流向另一处。C++形象地将此过程称为流(Stream)。C++的输入输出流是指由若干字节组成的宇节序列。在输入操作时,字节流从输入设备(如键盘、磁盘)流向内存,在输出操作时,字节流从内存流向输出设备(如屏幕、打印机、磁盘等)。流中的内容可以是ASCII字符、二进制形式的数据、图形图像、数字音频视频或其他形式的信息。
实际上,在内存中为每一个数据流开辟一个内存缓冲区,用来存放流中的数据。当用cout和插入运算符“<<”向显示器输出数据时,先将这些数据送到程序中的输出缓冲区保存,直到缓冲区满了或遇到endl,就将缓冲区中的全部数据送到显示器显示出来。在输入时,从键盘输入的数据先放在键盘的缓冲区中,当按回车键时,键盘缓冲区中的数据输入到程序中的输入缓冲区,形成cin流,然后用提取运算符“ >>”从输入缓冲区中提取数据送给程序中的有关变量。总之,流是与内存缓冲区相对应的,或者说,缓冲区中的数据就是流。
在C++中,输入输出流被定义为类。C++的I/O库中的类称为流类(stream class)。 用流类定义的对象称为流对象。
表1.1 I/O类库
https://blog.csdn.net/u012372584/article/details/39186129 更多I/O 详解
2 .getch(): 所在头文件:conio.h 函数用途:从控制台读取一个字符,但不显示在屏幕上
程序结尾加上getch()让程序运行窗口(dos窗口)停留显示。会等待你按下任意键之后,把该键字符所对应的ASCII码赋给ch,再执行下面的语句。
3. %-10s
- 左对齐 10 宽度 s字符串
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<conio.h>
#include<dos.h>
//telebook 结构体占用的字节数
#define LEN sizeof(struct telebook)
#define FORMAT "%-10s%-15s%-25s%-30s\n"
#define DATA info[i].name,info[i].tel,info[i].email,info[i].address
struct telebook{
char name[10];
char tel[15];
char email[25];
char address[30];
};
struct telebook info[100];//结构体数组 每一个元素都是一个telebook结构体
//函数声明
void input();
void add();
void search();
void update();
void del();
void display();
void sort();
void menu();
void menu(){
system("cls");//调用system函数来清零
printf("\n\n\n\n\n");
printf("\t\t|--------contact--------------|\n");//\t tab
printf("\t\t| 0. exit |\n");
printf("\t\t| 1. add |\n");
printf("\t\t| 2. search |\n");
printf("\t\t| 3. update |\n");
printf("\t\t| 4. del |\n");
printf("\t\t| 5. sort |\n");
printf("\t\t| 6.displayall |\n");
printf("\t\t| --------------------------|\n");
printf("\t\t| please choose(0-6) |\n");
}
int main(){
int n;
menu();
scanf("%d",&n);
while(n){
switch(n){
case 1: input(); break;
case 2: search(); break;
case 3: update(); break;
case 4: del(); break;
case 5:sort(); break;
case 6: display(); break;
default: break;
}
getch();
menu();
scanf("%d",&n);
}
return 0;
}
void input(){
int i,count=0;
char ch[2];
FILE *fp;//指向文件的指针变量
//打开失败的话
if((fp=fopen("data.txt","a+"))==NULL) {
//以附加形式打开文件,不存在则新建,存在则附加信息在文件尾部 ,文件打开失败 指针会返回空值
printf("can not open\n");
return;
}
while(!feof(fp)){
//检测结束符 EOF就是结束 feof函数遇到EOF返回0
//没有结束的话,统计文件中的记录条数,读取到结构体数组中
if(fread(&info[count],LEN,1,fp)==1)
//接受数据初始地址 字节数 每次读取数据项个数 输入流(从哪个文件读)
count++;
}
fclose(fp);//内存操作 关闭文件
//当前是通讯录是否为空
if(count==0)
printf("no record\n");
//不为空先清零
else{
system("cls");
display();
}
//打开失败的话
if((fp=fopen("data.txt","wb"))==NULL) {
//只写 打开
printf("open fail\n");
return;
}
for(i=0;i<count;i++)
//把info内容又写回磁盘文件data中
fwrite(&info[count],LEN,1,fp);
printf("please input(y/n)");
scanf("%s",ch);
while(strcmp(ch,"y")==0) {
printf("name:");
scanf("%s",&info[count].name);
//看看是不是存过了