通讯录3.0(文件存储)

简介: 文件写入 通讯录

 

目录

改进

1.读取信息

2.写入信息

完整代码

config.h

utili.h

contact.h

contact.cpp

contactMain.cpp


前面我们先用静态写了通讯录,后面改进换成了动态,但是我们发现还是有很大的问题,就是每次运行都要增加人员,非常的麻烦。

简易通讯录(C语言)

通讯录2.0(动态)

所以我们这次用文件处理,将增加的人员信息保存到文件中,下次运行直接从文件中提取人员信息,将会方便很多。

改进

1.读取信息

void LoadContact(Contact *pcont)
{
  assert(pcont != NULL);
  FILE *fp = fopen("cont.dat", "r");
  if (fp == NULL)
  {
    printf("读取通讯录文件失败.....\n");
    return;
  }
  int idx = 0;
  while (1)
  {
    if (IsFullContact(pcont) && !_Inc(pcont))
      break;
    int res = fscanf(fp, "%s %s %d %s %s", pcont->cont[idx].name,
      pcont->cont[idx].sex,
      &pcont->cont[idx].age,
      pcont->cont[idx].tel,
      pcont->cont[idx].address);
    if (res == EOF)
      break;
    idx++;
    pcont->size++;
  }
  fclose(fp);
}

image.gif

2.写入信息

void SaveContact(Contact *pcont)
{
  assert(pcont != NULL);
  FILE *fp = fopen("cont.dat", "w");
  if (fp == NULL)
  {
    printf("写入通讯录文件失败.....\n");
    return;
  }
  for (int i = 0; i<pcont->size; ++i)
  {
    fprintf(fp, "%-10s%-5s%-6d%-13s%s\n", pcont->cont[i].name,
      pcont->cont[i].sex,
      pcont->cont[i].age,
      pcont->cont[i].tel,
      pcont->cont[i].address);
  }
  fclose(fp);
#ifdef DISPLAY
  printf("写入数据成功.\n");
#endif
}

image.gif

完整代码

config.h

#ifndef _CONFIG_H_
#define _CONFIG_H_
//#define DISPLAY
#endif /* _CONFIG_H_ */

image.gif

utili.h

#ifndef _UTILI_H_
#define _UTILI_H_
#include<stdio.h>
#include<assert.h>
#include<string.h>
#include<stdbool.h>
#include<malloc.h>
#endif /* _UTILI_H_ */

image.gif

contact.h

#ifndef _CONTACT_H_
#define _CONTACT_H_
#include"utili.h"
enum { QUIT, ADD, DEL, FIND, MODIFY, SHOW, CLEAR, SORT };
#define MAX_NAME_SIZE 10
#define MAX_SEX_SIZE   3
#define MAX_TEL_SIZE   12
#define MAX_ADDR_SIZE 128
//#define MAX_CONTACT_SIZE 2
#define DEFAULT_CONTACT_SIZE 2
//定义通讯录人员信息
typedef struct PersonInfo
{
  char name[MAX_NAME_SIZE];
  char sex[MAX_SEX_SIZE];
  int age;
  char tel[MAX_TEL_SIZE];
  char address[MAX_ADDR_SIZE];
}PersonInfo;
//定义通讯录结构
typedef struct Contact
{
  //PersonInfo cont[MAX_CONTACT_SIZE]; //静态开辟
  PersonInfo *cont;   //动态开辟
  size_t     capacity;
  size_t     size;
}Contact;
/////////////////////////////////////////////////////////////
bool IsFullContact(Contact *pcont);
void InitContact(Contact *pcont);
void AddContact(Contact *pcont);
void ShowContact(Contact *pcont);
int  FindContact(Contact *pcont);
void DelContact(Contact *pcont);
void ModifyContact(Contact *pcont);
void SortContact(Contact *pcont);
void ClearContact(Contact *pcont);
void DestroyContact(Contact *pcont);
//数据序列化
void SaveContact(Contact *pcont);
void LoadContact(Contact *pcont);
#endif /* _UTILI_H_ */

image.gif

contact.cpp

#include"contact.h"
#include"config.h"
void InitContact(Contact *pcont)
{
  assert(pcont != NULL);
  pcont->cont = (PersonInfo*)malloc(sizeof(PersonInfo)* DEFAULT_CONTACT_SIZE);
  memset(pcont->cont, 0, sizeof(PersonInfo)* DEFAULT_CONTACT_SIZE);
  pcont->capacity = DEFAULT_CONTACT_SIZE;
  pcont->size = 0;
  /////////////////////////////////////////////////////////////////////////////
  LoadContact(pcont);
}
static bool _Inc(Contact *pcont)
{
  PersonInfo *new_cont = (PersonInfo *)realloc(pcont->cont, sizeof(PersonInfo)*(pcont->capacity * 2));
  if (new_cont == NULL)
  {
    printf("内存不足,扩容失败......\n");
    return false;
  }
  pcont->cont = new_cont;
  pcont->capacity *= 2;
  return true;
}
bool IsFullContact(Contact *pcont)
{
  assert(pcont != NULL);
  return pcont->size >= pcont->capacity;
}
void AddContact(Contact *pcont)
{
  assert(pcont != NULL);
  if (IsFullContact(pcont) && !_Inc(pcont))
  {
    printf("通讯录空间已满,不能新增信息.....\n");
    return;
  }
  printf("姓名:>");
  scanf("%s", pcont->cont[pcont->size].name);
  printf("性别:>");
  scanf("%s", pcont->cont[pcont->size].sex);
  printf("年龄:>");
  scanf("%d", &pcont->cont[pcont->size].age);
  printf("电话:>");
  scanf("%s", pcont->cont[pcont->size].tel);
  printf("住址:>");
  scanf("%s", pcont->cont[pcont->size].address);
  pcont->size++;
#ifdef DISPLAY
  printf("增加完成.......\n");
#endif
}
void ShowContact(Contact *pcont)
{
  assert(pcont != NULL);
  printf("%-10s%-5s%-6s%-13s%s\n", "姓名", "性别", "年龄", "电话", "住址");
  for (int i = 0; i<pcont->size; ++i)
  {
    printf("%-10s%-5s%-6d%-13s%s\n", pcont->cont[i].name,
      pcont->cont[i].sex,
      pcont->cont[i].age,
      pcont->cont[i].tel,
      pcont->cont[i].address);
  }
}
int  FindContact(Contact *pcont)
{
  assert(pcont != NULL);
  printf("请输入要查找的姓名:>");
  char name[MAX_NAME_SIZE] = { 0 };
  scanf("%s", name);
  printf("%-10s%-5s%-6s%-13s%s\n", "姓名", "性别", "年龄", "电话", "住址");
  for (int i = 0; i<pcont->size; ++i)
  {
    if (strcmp(name, pcont->cont[i].name) == 0)
    {
      printf("%-10s%-5s%-6d%-13s%s\n", pcont->cont[i].name,
        pcont->cont[i].sex,
        pcont->cont[i].age,
        pcont->cont[i].tel,
        pcont->cont[i].address);
      return i;
    }
  }
  return -1;
}
void DelContact(Contact *pcont)
{
  assert(pcont != NULL);
  printf("请输入要删除的名字:>");
  char name[MAX_NAME_SIZE] = { 0 };
  scanf("%s", name);
  int i;
  for (i = 0; i<pcont->size; ++i)
  {
    if (strcmp(name, pcont->cont[i].name) == 0)
      break;
  }
  if (i >= pcont->size)
  {
    printf("要删除的信息不存在.....\n");
    return;
  }
  for (int k = i; k<pcont->size - 1; ++k)
    pcont->cont[k] = pcont->cont[k + 1];
  pcont->size--;
#ifdef DISPLAY
  printf("删除完成.......\n");
#endif
}
void ModifyContact(Contact *pcont)
{
  assert(pcont != NULL);
  printf("请输入要修改的名字:>");
  char name[MAX_NAME_SIZE] = { 0 };
  scanf("%s", name);
  int i;
  for (i = 0; i<pcont->size; ++i)
  {
    if (strcmp(name, pcont->cont[i].name) == 0)
      break;
  }
  if (i >= pcont->size)
  {
    printf("要修改的信息不存在.....\n");
    return;
  }
  printf("你想修改什么信息(1-姓名 2-性别 3-年龄 4-电话 5-住址)\n");
  int select;
  scanf("%d", &select);
  if (select == 1)
  {
    printf("请输入要修改姓名:>");
    scanf("%s", pcont->cont[i].name);
  }
  else if (select == 2)
  {
    printf("请输入要修改性别:>");
    scanf("%s", pcont->cont[i].sex);
  }
  else if (select == 3)
  {
    printf("请输入要修改住址:>");
    scanf("%d", &pcont->cont[i].age);
  }
  else if (select == 4)
  {
    printf("请输入要修改电话:>");
    scanf("%s", pcont->cont[i].tel);
  }
  else if (select == 5)
  {
    printf("请输入要修改性别:>");
    scanf("%s", pcont->cont[i].address);
  }
#ifdef DISPLAY
  printf("修改完成.......\n");
#endif
}
void SortContact(Contact *pcont)
{
  assert(pcont != NULL);
  for (int i = 0; i<pcont->size - 1; ++i)
  {
    for (int j = 0; j<pcont->size - 1 - i; ++j)
    {
      if (strcmp(pcont->cont[j].name, pcont->cont[j + 1].name) > 0)
      {
        PersonInfo tmp = pcont->cont[j];
        pcont->cont[j] = pcont->cont[j + 1];
        pcont->cont[j + 1] = tmp;
      }
    }
  }
#ifdef DISPLAY
  printf("排序完成.......\n");
#endif
}
void ClearContact(Contact *pcont)
{
  assert(pcont != NULL);
  pcont->size = 0;
#ifdef DISPLAY
  printf("清除完成.......\n");
#endif
}
void DestroyContact(Contact *pcont)
{
  assert(pcont != NULL);
  free(pcont->cont);
  pcont->cont = NULL;
  pcont->capacity = pcont->size = 0;
#ifdef DISPLAY
  printf("摧毁通讯录成功.\n");
#endif
}
void LoadContact(Contact *pcont)
{
  assert(pcont != NULL);
  FILE *fp = fopen("cont.dat", "r");
  if (fp == NULL)
  {
    printf("读取通讯录文件失败.....\n");
    return;
  }
  int idx = 0;
  while (1)
  {
    if (IsFullContact(pcont) && !_Inc(pcont))
      break;
    int res = fscanf(fp, "%s %s %d %s %s", pcont->cont[idx].name,
      pcont->cont[idx].sex,
      &pcont->cont[idx].age,
      pcont->cont[idx].tel,
      pcont->cont[idx].address);
    if (res == EOF)
      break;
    idx++;
    pcont->size++;
  }
  fclose(fp);
}
void SaveContact(Contact *pcont)
{
  assert(pcont != NULL);
  FILE *fp = fopen("cont.dat", "w");
  if (fp == NULL)
  {
    printf("写入通讯录文件失败.....\n");
    return;
  }
  for (int i = 0; i<pcont->size; ++i)
  {
    fprintf(fp, "%-10s%-5s%-6d%-13s%s\n", pcont->cont[i].name,
      pcont->cont[i].sex,
      pcont->cont[i].age,
      pcont->cont[i].tel,
      pcont->cont[i].address);
  }
  fclose(fp);
#ifdef DISPLAY
  printf("写入数据成功.\n");
#endif
}

image.gif

contactMain.cpp

#include"contact.h"
void Menu()
{
  printf("****************通 讯 录****************\n");
  printf("*   [1] Add                 [2] Del    *\n");
  printf("*   [3] Find                [4] Modify *\n");
  printf("*   [5] Show                [6] Clear  *\n");
  printf("*   [7] Sort                [0] Quit   *\n");
  printf("****************************************\n");
}
void main()
{
  Contact cont;
  InitContact(&cont);
  int select = 1;
  while (select)
  {
    Menu();
    printf("请选择:>");
    scanf("%d", &select);
    if (select == QUIT)
      break;
    switch (select)
    {
    case ADD:
      AddContact(&cont);
      break;
    case DEL:
      DelContact(&cont);
      break;
    case FIND:
      FindContact(&cont);
      break;
    case MODIFY:
      ModifyContact(&cont);
      break;
    case SHOW:
      ShowContact(&cont);
      break;
    case CLEAR:
      ClearContact(&cont);
      break;
    case SORT:
      SortContact(&cont);  //qsort
      break;
    }
  }
  SaveContact(&cont);
  DestroyContact(&cont);
}

image.gif

相关文章
|
存储 文件存储 C语言
【C语言】通讯录3.0 (文件存储版)
通讯录是一种记录联系人信息的工具,包括姓名、电话号码、电子邮件地址、住址等。 文章的一二三章均于上一篇相同,可以直接看第四章改造内容。 此通讯录是基于通讯录2.0(动态增长版)的基础上进行增加文件操作功能,请先看系列文章第二篇,再看本篇博客。
49 1
|
存储 文件存储
详解通讯录(静态版、动态增长版、文件存储版)(下)
详解通讯录(静态版、动态增长版、文件存储版)(下)
69 0
详解通讯录(静态版、动态增长版、文件存储版)(下)
|
存储 搜索推荐 文件存储
详解通讯录(静态版、动态增长版、文件存储版)(上)
详解通讯录(静态版、动态增长版、文件存储版)(上)
133 0
详解通讯录(静态版、动态增长版、文件存储版)(上)
|
存储 运维 监控
阿里云的文件存储NAS使用心得
阿里云的文件存储NAS使用心得
363 0
|
存储 弹性计算 固态存储
阿里云服务器1TB存储收费标准(数据盘/对象存储OSS/文件存储NAS)
阿里云服务器1TB存储多少钱?系统盘最大可选到500GB,数据盘选到1TB价格为3655元一年。也可以选择对象存储OSS和文件存储NAS
6195 2
阿里云服务器1TB存储收费标准(数据盘/对象存储OSS/文件存储NAS)
|
存储 弹性计算 人工智能
阿里云文件存储NAS通用型、极速型和文件存储CPFS有什么区别?
阿里云文件存储NAS极速型NAS低时延,适合企业级时延敏感型核心业务;文件存储CPFS拥有高吞吐和高IOPS,适合高性能计算业务;通用型NAS大容量、高性价比、弹性扩展,支持低频介质,适合通用类文件共享业务。
1727 0
阿里云文件存储NAS通用型、极速型和文件存储CPFS有什么区别?
|
4月前
|
存储 NoSQL 文件存储
云计算问题之阿里云文件存储CPFS如何满足大模型智算场景的存储需求
云计算问题之阿里云文件存储CPFS如何满足大模型智算场景的存储需求
|
存储 弹性计算 并行计算
在高性能计算(HPC)场景下,阿里云存储的文件存储产品的实践
在高性能计算(HPC)场景下,阿里云存储的文件存储产品具有以下的应用需求和实践
427 4
|
存储 弹性计算 监控
|
弹性计算 Linux DataWorks
阿里云ecs搭建简易ftp服务器-用于DataWorks文件存储及依赖校验
很多企业客户在使用阿里云产品时,经常需要与FTP服务器进行文件交互,诸如跨IDC任务done文件依赖,跨账号、部门临时数据交互等场景。这里简要记录阿里云ecs搭建简易ftp服务器用于上述场景答疑的过程。