动态的文件版本的通讯录

都在stdlib.h函数库内
它们的返回值都是请求系统分配的地址,如果请求失败就返回NULL 

malloc用于申请一段新的地址,参数size为需要内存空间的长度,如: 
char* p; 
p=(char*)malloc(20);

calloc与malloc相似,参数sizeOfElement为申请地址的单位元素长度,numElements为元素个数,如: 
char* p; 
p=(char*)calloc(20,sizeof(char)); 
这个例子与上一个效果相同

realloc是给一个已经分配了地址的指针重新分配空间,参数ptr为原有的空间地址,newsize是重新申请的地址长度,如: 
char* p; 
p=(char*)malloc(sizeof(char)*20); 
p=(char*)realloc(p,sizeof(char)*40);

注意,这里的空间长度都是以字节为单位。 

C语言的标准内存分配函数:malloc,calloc,realloc,free等。 
malloc与calloc的区别为1块与n块的区别: 
malloc调用形式为(类型*)malloc(size):在内存的动态存储区中分配一块长度为“size”字节的连续区域,返回该区域的首地址。 
calloc调用形式为(类型*)calloc(n,size):在内存的动态存储区中分配n块长度为“size”字节的连续区域,返回首地址。 
realloc调用形式为(类型*)realloc(*ptr,size):将ptr内存大小增大到size。 

free的调用形式为free(void*ptr):释放ptr所指向的一块内存空间。 
C++中为new/delete函数。



fopen()函数用来打开一个文件,其调用的一般形式为: 文件指针名=fopen(文件名,使用文件方式)
 其中,“文件指针名”必须是被说明为FILE 类型的指针变量,“文件名”是被打开文件的文件名。 
“使用文件方式”是指文件的类型和操作要求。“文件名”是字符串常量或字符串数组。例如: 
FILE *fp;
fp=("file a","r");
      "r"           打开文字文件只读
           "w"          创建文字文件只写
           "a"          增补,如果文件不存在则创建一个
           "r+"         打开一个文字文件读/写
           "w+"         创建一个文字文件读/写
           "a+"         打开或创建一个文件增补
           "b"          二进制文件(可以和上面每一项合用)
           "t"           文这文件(默认项)
“rt”      只读打开一个文本文件,只允许读数据 
“wt”      只写打开或建立一个文本文件,只允许写数据
“at”      追加打开一个文本文件,并在文件末尾写数据
“rb”      只读打开一个二进制文件,只允许读数据
“wb”       只写打开或建立一个二进制文件,只允许写数据
“ab”       追加打开一个二进制文件,并在文件末尾写数据
“rt+”      读写打开一个文本文件,允许读和写
“wt+”      读写打开或建立一个文本文件,允许读写
“at+”      读写打开一个文本文件,允许读,或在文件末追加数 据
“rb+”      读写打开一个二进制文件,允许读和写 
“wb+”      读写打开或建立一个二进制文件,允许读和写
“ab+”      读写打开一个二进制文件,允许读,或在文件末追加数据
1. 文件使用方式由r,w,a,t,b,+六个字符拼成,各字符的含义是:
r(read): 读
w(write): 写
a(append): 追加
t(text): 文本文件,可省略不写
b(banary): 二进制文件
+: 读和写
2. 凡用“r”打开一个文件时,该文件必须已经存在, 且只能从该文件读出。
3. 用“w”打开的文件只能向该文件写入。 若打开的文件不存在,则以指定的文件名建立该文件,若打开的文件已经存在,则将该文件删去,重建一个新文件。

4. 若要向一个已存在的文件追加新的信息,只能用“a ”方式打开文件。但此时该文件必须是存在的,否则将会出错。

5. 在打开一个文件时,如果出错,fopen将返回一个空指针值NULL。在程序中可以用这一信息来判别是否完成打开文件的工作,并作相应的处理。因此常用以下程序段打开文件:
if((fp=fopen("c:\\hzk16","rb")==NULL)
{
printf("\nerror on open c:\\hzk16 file!");
getch();
exit(1);
}
  这段程序的意义是,如果返回的指针为空,表示不能打开C盘根目录下的hzk16文件,则给出提示信息“error on open c:\ hzk16file!”,下一行getch()的功能是从键盘输入一个字符,但不在屏幕上显示。在这里,该行的作用是等待, 只有当用户从键盘敲任一键时,程序才继续执行, 因此用户可利用这个等待时间阅读出错提示。敲键后执行exit(1)退出程序。

6. 把一个文本文件读入内存时,要将ASCII码转换成二进制码, 而把文件以文本方式写入磁盘时,也要把二进制码转换成ASCII码,因此文本文件的读写要花费较多的转换时间。对二进制文件的读写不存在这种转换。

7. 标准输入文件(键盘),标准输出文件(显示器 ),标准出错输出(出错信息)是由系统打开的,可直接使用。文件关闭函数fclose文件一旦使用完毕,应用关闭文件函数把文件关闭, 以避免文件的数据丢失等错误。
fclose()函数
   fclose()函数用来关闭一个由fopen()函数打开的文件 , 其调用格式为:
   int fclose(FILE *stream);
   该函数返回一个整型数。当文件关闭成功时, 返回0, 否则返回一个非零值。可以根据函数的返回值判断文件是否关闭成功。 
例子:
FILE *fpOut=fopen(“c:\\a.txt”,”wt+”);
Int a=1;
Fprintf(fpOut,”%d”,a);
Fclose(fpOut);

//contact.h
#ifndef __CONTACT_H__
#define __CONTACT_H__

#define MAX 1000
#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 30

#define CAPACITY 2

#define INC_CAPACITY 20

typedef struct peoinfo
{
	char name[NAME_MAX];
	char sex[SEX_MAX];
	int age;
	char tele[TELE_MAX];
	char addr[ADDR_MAX];
}peoinfo;
typedef struct contact
{
	peoinfo* data;
	int sz;
}contact;
void init_contact(contact* pcon);
void add_contact(contact* pcon);
void del_contact(contact* pcon);
void find_contact(contact* pcon);
void modify_contact(contact* pcon);
void display_contact(contact* pcon);
void empty_contact(contact* pcon);
void name_sort(contact* pcon);
void load_info(contact* pcon);
void save_info(contact* pcon);
#endif
//contact.c
#define _CRT_SECURE_NO_DEPRECATE 1

#include<stdio.h>
#include"contact.h"
#include<string.h>
#include<stdlib.h>
#include<errno.h>

void display_contact(contact* pcon);

int find_peo(contact* pcon)
{
	char name[NAME_MAX] = { 0 };
	int j = 0;
	int i = 0;
	printf("请输入姓名:>");
	scanf("%s", name);
	printf("%-10s%-10s%-10s%-10s%-10s\n", "name", "sex", "age", "tele", "addr");
	for (i = 0; i < pcon->sz; i++)
	{
		if (strcmp(name, pcon->data[i].name) == 0)
		{
			break;
		}
	}
	if (i == pcon->sz)
	{		
		return -1;
	}
	return i;
}

void init_contact(contact* pcon)
{
	pcon->data = malloc(CAPACITY*sizeof(peoinfo));
	pcon->sz = 0;
	pcon->capacity = CAPACITY;
	memset(pcon->data, 0, CAPACITY*sizeof(peoinfo));
}

void INC_capacity(contact* pcon)
{
	if (pcon->sz >= pcon->capacity)
	{
		peoinfo *p = (peoinfo*)realloc(pcon->data, (pcon->capacity + INC_CAPACITY)*sizeof(peoinfo));
		if (p != NULL)
		{
			pcon->data = p;
			pcon->capacity += INC_CAPACITY;
			//printf("开辟成功!\n");
		}
		else
		{
			perror("realloc");
		}
	}
}
void add_contact(contact* pcon)
{
	INC_capacity(pcon);
	printf("姓名:>");
	scanf("%s", pcon->data[pcon->sz].name);
	printf("性别:>");
	scanf("%s", pcon->data[pcon->sz].sex);
	printf("年龄:>");
	scanf("%d", &(pcon->data[pcon->sz].age));
	printf("电话:>");
	scanf("%s", pcon->data[pcon->sz].tele);
	printf("地址:>");
	scanf("%s", pcon->data[pcon->sz].addr);
	pcon->sz++;
}
void del_contact(contact* pcon)
{
	int j = 0;
	int p = find_peo(pcon);
	printf("%-10s%-10s%-10d%-15s%-10s",
		pcon->data[p].name,
		pcon->data[p].sex,
		pcon->data[p].age,
		pcon->data[p].tele,
		pcon->data[p].addr);
	if (p == -1)
	{
		printf("没有你要删除的人!\n");
		return;
	}
	
	for (j = p; j < pcon->sz - 1; j++)
	{
		pcon->data[j] = pcon->data[j + 1];
	}
	pcon->sz--;
	printf("删除成功!\n");
	
}

void find_contact(contact* pcon)
{
	int p = find_peo(pcon);
	if (p == -1)
	{
		printf("没有你要找的人!\n");
	}
	else
	{
		printf("%-10s%-10s%-10d%-15s%-10s",
			pcon->data[p].name,
			pcon->data[p].sex,
			pcon->data[p].age,
			pcon->data[p].tele,
			pcon->data[p].addr);
	}
	
}
void modify_contact(contact* pcon)
{
	enum{
		EXIT,
		NAME,
		SEX,
		AGE,
		TELE,
		ADDR
	};
	int p = find_peo(pcon);
	int input = 0;
	if (p == -1)
	{
		printf("没有你要找的人!\n");
	}
	else
	{
		printf("%-10s%-10s%-10d%-15s%-10s",
			pcon->data[p].name,
			pcon->data[p].sex,
			pcon->data[p].age,
			pcon->data[p].tele,
			pcon->data[p].addr);
	}
	printf("\n");
	printf("********************************\n");
	printf("******* 1.name    2.sex  *******\n");
	printf("******* 3.age     4.tele *******\n");
	printf("******* 5.addr    0.exit *******\n");
	printf("********************************\n");
	printf("请选择:>");
	scanf("%d", &input);
	switch (input)
	{
	case EXIT:
		break;
	case NAME:
		printf("名字:>");
		scanf("%s", pcon->data[p].name);
		break;
	case SEX:
		printf("性别:>");
		scanf("%s", pcon->data[p].sex);
		break;
	case AGE:
		printf("年龄:>");
		scanf("%d", &(pcon->data[p].age));
		break;
	case TELE:
		printf("电话:>");
		scanf("%s", pcon->data[p].tele);
		break;
	case ADDR:
		printf("地址:>");
		scanf("%s", pcon->data[p].addr);
		break;
	default:
		printf("输入有误!\n");
		break;
	}
	printf("修改成功!\n");
}
void display_contact(contact* pcon)
{
	int i = 0;
	printf("%-10s%-10s%-10s%-15s%-10s\n", "name", "sex", "age", "tele", "addr");
	for (i = 0; i < pcon->sz; i++)
	{
		printf("%-10s%-10s%-10d%-15s%-10s\n",
			pcon->data[i].name,
			pcon->data[i].sex,
			pcon->data[i].age,
			pcon->data[i].tele,
			pcon->data[i].addr);
	}
	printf("显示完毕!\n\n");
}
void empty_contact(contact* pcon)
{
	pcon->sz = 0;
	printf("清空完毕!\n");
}


void name_sort(contact* pcon)
{
	int i = 0;
	for (i = 0; i < pcon->sz - 1; i++)
	{
		int j = 0;
		for (j = 0; j < pcon->sz - 1 - i; j++)
		{
			if (strcmp(pcon->data[j].name, pcon->data[j + 1].name)>0)
			{
				peoinfo s = pcon->data[j];
				pcon->data[j] = pcon->data[j + 1];
				pcon->data[j + 1] = s;
			}
		}
	}
	display_contact(pcon);
	printf("排序成功!\n");
}
void save_info(contact* pcon)
{
	FILE* pf = fopen("contact.txt", "w+");
	int i = 0;
	if (pf == NULL)
	{
		perror("fopen");
		exit(EXIT_FAILURE);
	}
	fprintf(pf, "%d\n", pcon->sz);
	for (i = 0; i < pcon->sz; i++)
	{
		fprintf(pf,"%s %s %d %s %s\n",
			pcon->data[i].name,
			pcon->data[i].sex,
			pcon->data[i].age,
			pcon->data[i].tele,
			pcon->data[i].addr);

	}
	free(pcon->data);
	fclose(pf);
}
void load_info(contact* pcon)
{
	FILE* pf = fopen("contact.txt", "r");
	int i = 0;
	if (pf == NULL)
	{
		perror("fopen");
		exit(EXIT_FAILURE);
	}
	fscanf(pf, "%d\n", &(pcon->sz));
	
	for (i = 0; i < pcon->sz; i++)
	{
		INC_capacity(pcon);
		fscanf(pf, "%s %s %d %s %s\n",
			pcon->data[i].name,
			pcon->data[i].sex,
			&(pcon->data[i].age),
			pcon->data[i].tele,
			pcon->data[i].addr);
	}
	fclose(pf);
}


//test.c

#define _CRT_SECURE_NO_DEPRECATE 1
#include<stdio.h>
#include"contact.h"
#include<windows.h>

void menu()
{
	printf("*************************************\n");
	printf("*************************************\n");
	printf("*************************************\n");
	printf("*********    通   讯   录     *******\n");
	printf("*********  1.添加     2.删除  *******\n");
	printf("*********  3.查找     4.修改  *******\n");
	printf("*********  5.显示     6.清空  *******\n");
	printf("*********  7.排序     0.退出  *******\n");
	printf("*************************************\n");
	printf("*************************************\n");
	printf("*************************************\n");
}

int main()
{

	contact my_con;
	int input = 0;
	init_contact(&my_con);
	load_info(&my_con);
	do
	{
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case 0:
			break;
		case 1:
			add_contact(&my_con);
			break;
		case 2:
			del_contact(&my_con);
			break;
		case 3:
			find_contact(&my_con);
			break;
		case 4:
			modify_contact(&my_con);
			break;
		case 5:
			display_contact(&my_con);
			break;
		case 6:
			empty_contact(&my_con);
			break; 
		case 7:
			name_sort(&my_con);
			break;
		default:
			printf("选择错误,请重新输入:>");
			break;
		}
	} while (input);
	save_info(&my_con);
	system("pause");
	return 0;
}


























  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值