以文本方式查看主题

-  中文XML论坛 - 专业的XML技术讨论区  (http://bbs.xml.org.cn/index.asp)
--  『 C/C++编程思想 』  (http://bbs.xml.org.cn/list.asp?boardid=61)
----  如何用链表来实现的简易通讯录?  (http://bbs.xml.org.cn/dispbbs.asp?boardid=61&rootid=&id=88045)


--  作者:葛靖青001
--  发布时间:11/30/2010 8:48:00 AM

--  如何用链表来实现的简易通讯录?
【转自互联网】

#include <stdio.h>

  #include <stdlib.h>

  #include <string.h>

  #define B_PUT         puts("+-----------------------------------------------------------------+");        
  puts("|姓名                地址                          联系方式       |")

  #define END_PUT puts("+-----------------------------------------------------------------+")

  #define INPUT_NAME puts("请输入联系人姓名:");
  setbuf(stdin,(char *)0);
  scanf("%[^\n]",name)//用与修改,查找,删除时,输入name.由于操作频繁,定义为宏

  #define FRESH getchar();
  getchar()//一个接受上次的Enter,另一个等待输入Enter.用于Press Enter to Continue

  /*存放通讯录信息单链表定义*/

  typedef struct

  {

  char name[20];

  char address[30];

  char tel[20];

  }inf_t;

  typedef struct node

  {

  inf_t date;

  struct node *next;

  }*link;

  inf_t getInf(void);

  void insert(inf_t inf);

  link pop(const char *name,link *pre);

  void del(link pre,link cur);

  void outputOne(link p);

  void output(void);

  void menu(void);

  int save(void);

  void openfile(void);

  link head = NULL;

  inf_t getInf(void) //获取联系人信息

  {

  inf_t t_get;

  char *pch;

  printf("\t联系人姓名:");

  setbuf(stdin,(char *)0);

  scanf("%[^\n]",t_get.name); //存入除换行以外的所有字符

  printf("\t该联系人地址:");

  setbuf(stdin,(char *)0);

  scanf("%[^\n]",t_get.address);

  lableTel:

  printf("\t电话或手机号码:");

  setbuf(stdin,(char *)0);

  scanf("%s",t_get.tel);

  /*处理当号码不为数字的情况*/

  for(pch = t_get.tel; *pch != '\0'; pch++){

  if(*pch < '0' || *pch > '9'){

  puts("该通讯录暂只支持纯数字的电话号码!");

  goto lableTel;

  }

  }

  return t_get;

  }

  void insert(inf_t inf)//创建一个新结点,数据域存放inf,通过头插法插入单链表

  {

  link p = (struct node *)malloc(sizeof *p);

  p->date = inf;

  p->next = head;

  head = p;

  }
/*匹配单链表中为姓名项为name的节点 pre为指向该节点前一项的指针的指针 */

  link pop(const char *name,link *pre){

  link p = head;

  while(p != NULL){

  if(strcmp(name,p->date.name) == 0){

  return p;

  }

  *pre = p;

  p = p->next;

  }

  return NULL;

  }

  void del(link pre,link cur) //删除cur结点,pre为cur前一个结点

  {

  if(cur == head){

  head = cur->next;

  }

  else pre->next = cur->next;

  free(cur);

  }

  void outputOne(link p)

  {

  printf("|%-20s%-30s%-15s|\n",p->date.name,p->date.address,p->date.tel);

  }

  void output(void)

  {

  link p = head;

  B_PUT;

  while(p != NULL){

  outputOne(p);

  p = p->next;

  }

  END_PUT;

  }

  void menu(void)

  {

  puts("*************欢迎使用简易通讯录*************");

  puts("*\t+-------------------------+        *");

  puts("*\t|       1.添加记录        |        *");

  puts("*\t|       2.删除记录        |        *");

  puts("*\t|       3.查找记录        |        *");

  puts("*\t|       4.修改记录        |        *");

  puts("*\t|       5.显示所有记录    |        *");

  puts("*\t|       0.保存退出        |        *");

  puts("*\t+-------------------------+        *");

  puts("********************************************");

  printf("\t请输入您的选择:");

  }

  int save(void)

  {

  link p;

  FILE *ft = fopen("date.dat","wb");

  if(ft == NULL){

  perror("Savd file date.dat error");

  return 0;

  }

  while(head != NULL){

  fwrite(&head->date,sizeof(inf_t),1,ft);

  fflush(ft);

  p = head;

  head = head->next;

  free(p);//释放掉已存入文件的节点

  }

  fclose(ft);

  return 1;

  }

  void openfile(void)

  {

  inf_t tmp;

  FILE *ft = fopen("date.dat","rb");

  if(ft == NULL){

  perror("Open file date.dat error");

  return ;

  }

  while(fread(&tmp,sizeof(inf_t),1,ft) != 0){

  insert(tmp);

  fflush(ft);

  }

  fclose(ft);

  }
int main(void)

  {

  char cmd[10],name[15],*pch;

  int n;

  link p,pre = NULL;//p指向当前节点指针,pre指向当前节点前一节点的指针

  openfile();

  do{

  men:        system("cls");

  menu();

  setbuf(stdin,(char *)0);//清空输入流

  scanf("%[^\n]",cmd);//接受除换行以外的所有字符存入cmd中,并加上'\0'标志

  sscanf(cmd,"%d",&n);

  /*处理当命令不符合条件的情况*/

  if(strlen(cmd) != 1 || n < 0 || n > 5 || !(*cmd >= '0' && *cmd <= '9')){

  printf("\t输入错误或没有这个选项!");

  FRESH;

  goto men;

  }

  switch(n){

  case 1:insert(getInf());puts("\t添加成功!");break;

  case 2:

  INPUT_NAME;//提示输入姓名,然后将输入字符串存入name数组中

  if((p = pop(name,&pre)) != 0){

  del(pre,p);

  puts("\t删除成功!");

  }

  else puts("\t未找到任何相关信息!");

  break;

  case 3:

  INPUT_NAME;

  if((p = pop(name,&pre)) != 0){

  puts("\t\t\t找到的记录:");

  B_PUT;//打印通讯录的准备(美观)

  outputOne(p);

  END_PUT;//打印通讯录结束的处理(美观)

  }

  else puts("\t未找到任何相关信息!");

  break;

  case 4:

  INPUT_NAME;

  if((p = pop(name,&pre)) != 0){

  puts("\t\t\t找到的记录:");

  B_PUT;

  outputOne(p);

  END_PUT;

  printf("\t将此联系人地址修改为:");

  setbuf(stdin,(char *)0);

  scanf("%[^\n]",p->date.address);

  lable1:                                printf("\t将此联系人联系方式修改为:");

  setbuf(stdin,(char *)0);

  scanf("%[^\n]",p->date.tel);

  /*处理当号码不为数字的情况*/

  for(pch = p->date.tel; *pch != '\0'; pch++){

  if(*pch < '0' || *pch > '9'){

  puts("该通讯录暂只支持纯数字的电话号码!");

  goto lable1;

  }

  }

  puts("\t修改成功");

  }

  else puts("\t未找到任何相关信息!");

  break;

  case 5:system("cls");output();break;

  case 0:

  if(save() == 0)        puts("\t保存失败!");

  else puts("\t\t保存成功!");

  return 0;

  default :break;

  }

  printf("\tPress Enter To Continue!");

  FRESH;

  }while(n != 0);

  return 0;

  }


W 3 C h i n a ( since 2003 ) 旗 下 站 点
苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
76.172ms