zoukankan      html  css  js  c++  java
  • C语言编程练习:通讯录

    一、目标描述:

    1、建立一个通讯录,按姓名字母排序存储联系人信息。

    2、可显示菜单提供显示、新增、删除、修改等功能。

    3、显示:(1)显示联系人数量及全部联系人信息;(2)提供特定条件查询指定联系人信息。

    4、新增:逐步提示对应信息输入。

    5、删除:删除指定联系人信息。

    6、修改:提供特定条件修改指定单个联系人信息:先显示原先信息,再提供选项修改对应条目。

    7、通讯录信息保存在文件中。

    二、目标分析:

    1、项目需要排序、新增,则考虑使用二叉搜索树来建立数据堆模型。

    2、该模型须提供以下具体功能模块:(1)初始化(2)新增项目(3)删除(4)查询有无(5)修改

    3、信息要保存到文件中,每一次更新信息都要对应到文件中;则上述功能模块都要增加读写文件功能才能更新文件,这是一个复杂而且现阶段我很难实现的工作,只考虑下面一种很笨拙但相对简单的实现方式:在上述功能模块中:(2)新增(3)删除(5)修改功能后提供文件更新,同时文件更新不针对某条具体的(新增的或删除的或修改的)信息,而是对应功能完成后文件按整个通讯录重新写入。因此增加功能模块(6)将整个二叉树信息依序写入文件。

    4、程序第一次运行,文件信息为空,通过程序新增录入信息,并且文件得以更新,这没有问题。可第二次,第三次运行呢?文件已经存在,而且已经有信息了,可程序运行之初二叉树数据堆是空的,怎样读取文件中的信息,并写入二叉树模型呢?

    如果在文件中联系人信息如下设置:

    "Name:""-Bir_Year:""-..."可通过文本字符串判断然后写入二叉树的节点;另外一点,选择按姓名比较建立二叉树。同时,每个联系人信息结尾用换行符进行标记。

    三、功能模块的具体思路

    1、初始化

    先读取文本,建立二叉树联系人模型;若文本为空,则初始化空树。

    2、新增

    提示输入姓名,写入相关信息,建立节点,依据姓名找到合适位置插入二叉树。依据更新的二叉树,重新写入文本。

    3、删除

    提示输入被删姓名,删除该节点。依据更新的二叉树,重新写入文本。

    4、查询有无

    提示输入查询条件,找到相关信息并显示。该模块为功能2、3、5提供支持。

    5、修改

    提示输入被修改姓名,修改操作。依据更新的二叉树,重新写入文本。

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    
    void IniTree();
    void AddNode();
    void ChoiceAdd();
    void ShowTree();
    int SeekName();
    void ChoiceDel();
    void DeleteNode();
    void Choicefind();
    void Choicemod();
    void ShowMainInterface();
    void NodeWrite();
    
    
    
    typedef struct member
    {
       char name[20];
       char sex;
       char bir_year[5];
       char bir_month[3];
       char bir_day[3];
       char qq[15];
    }Member;
    
    typedef struct node
    {
       Member *person;
       struct node *left;
       struct node *right;
    }Node;
    
    typedef struct tree
    {
       Node *root;
       int numbers;
    }Tree;
    
    
    
    void ShowMainInterface()
    {
      printf("Input your choice:
    ");
      printf("a)show all friends.
    ");
      printf("b)add a friend's information.
    ");
      printf("c)modify a friend's information.
    ");
      printf("d)delete a friend.
    ");
      printf("e)look for a friend's information.
    ");
      printf("q)Quit.
    ");
    }
    void IniTree(Tree *ptree)
    {
      FILE *fp;
      Node *newnode;
      int i=0;
      char name[20];
      char sex;
      char bir_year[5];
      char bir_month[3];
      char bir_day[3];
      char qq[15];
      char ch;
      fp=fopen("c.txt","r");
    //如果文件不存在,则初始化二叉树
      if(fp==NULL)
      {
         ptree->root=NULL;
         ptree->numbers=0;
         printf("FILE Error!
    ");
      }
    //文件存在,则读入文件,创建二叉树节点信息
      else
      {
      ch=getc(fp);
    //每个换行符前为一个联系人信息,每行建一个节点
    //读文件前,先初始化树
      ptree->root=NULL;
      ptree->numbers=0;
      while(ch!=EOF)
      {
       while((ch!='
    ')&&(ch!=EOF))
       {
         newnode=(Node*)malloc(sizeof(Node));
         while(ch!='-')
         { 
             newnode->person->name[i]=ch;
             i++;
             ch=getc(fp);
         }
         newnode->person->name[i]='';
    //姓名信息录入完毕,重置i,继续读取下一个字符
         i=0;
         ch=getc(fp);
         while(ch!='-')
         { 
             newnode->person->sex=ch;
             ch=getc(fp);
         }
    //性别信息录入完毕,重置i,继续读取下一个字符
         i=0;
         ch=getc(fp);
         while(ch!='-')
         { 
             newnode->person->bir_year[i]=ch;
         i++;
             ch=getc(fp);
         }
         newnode->person->bir_year[i]='';
    //出生年信息录入完毕,重置i,继续读取下一个字符
         i=0;
         ch=getc(fp);
         while(ch!='-')
         { 
             newnode->person->bir_month[i]=ch;
         i++;
             ch=getc(fp);
         }
         newnode->person->bir_month[i]='';
    //出生月信息录入完毕,重置i,继续读取下一个字符
         i=0;
         ch=getc(fp);
         while(ch!='-')
         { 
             newnode->person->bir_day[i]=ch;
         i++;
             ch=getc(fp);
         }
         newnode->person->bir_day[i]='';
    //出生日信息录入完毕,重置i,继续读取下一个字符
         i=0;
         ch=getc(fp);
         while(ch!='-')
         { 
             newnode->person->qq[i]=ch;
         i++;
             ch=getc(fp);
         }
         newnode->person->qq[i]='';
    //qq信息录入完毕,该联系人所有信息录入完毕,建立该联系人节点信息,插入树
         newnode->left=NULL;
         newnode->right=NULL;
         AddNode(newnode,ptree);
    //此时ch到了行末,为'-'
    //继续读取下一个字符
         ch=getc(fp);
        }
    //单行节点信息录入完毕,重置i
        i=0;
        ch=getc(fp);
      }
     }
    }
         
    //使用前须确保无相同节点
    void AddNode(Node *node,Tree *ptree)
    {
       Node *newnode,*fathernode;
       newnode=ptree->root;
       while(newnode!=NULL)     //找空位,并且定位空位的父节点
       {
             if(strcmp(node->person->name,newnode->person->name)<0)
             {
                  fathernode=newnode;      
                  newnode=newnode->left;
             }
         else
             {
                  fathernode=newnode;      
                  newnode=newnode->right;
             }
        } 
           
        if(ptree->root==NULL)  //如果树为空
        {
               ptree->root=node;
               ptree->numbers++; 
        }
        else
        {
             if(strcmp(node->person->name,fathernode->person->name)<0)   //说明父节点左子节点为空
             {    
            fathernode->left=node;
            ptree->numbers++;
         }
             else
             {    
            fathernode->right=node;
            ptree->numbers++;
         }
         }
      
    }
    
    void ChoiceAdd(Tree *ptree)
    {
      Node *newnode;
      char namex[20];
      printf("please input the name:
    ");
      scanf("%s",namex);
      while(getchar()!='
    ') continue;
      if(SeekName(namex,ptree->root)==1)
        printf("the person:%s is exist.
    ",namex);
      else
      {
        newnode=(Node*)malloc(sizeof(Node));
        strcpy(newnode->person->name,namex);
        printf("
    please input the sex(F or M):
    ");
        scanf("%c",&(newnode->person->sex));while(getchar()!='
    ') continue;
        printf("
    please input the bir_year:
    ");
        scanf("%s",newnode->person->bir_year);while(getchar()!='
    ') continue;
        printf("
    please input the bir_month:
    ");
        scanf("%s",newnode->person->bir_month);while(getchar()!='
    ') continue;
        printf("
    please input the bir_day:
    ");
        scanf("%s",newnode->person->bir_day);while(getchar()!='
    ') continue;
        printf("
    please input the QQ:
    ");
        scanf("%s",newnode->person->qq);while(getchar()!='
    ') continue;
      
        newnode->left=NULL;
        newnode->right=NULL;
        AddNode(newnode,ptree);
        printf("-----%s information recorded!---------
    ",namex);
       }
    }
    
    void ShowTree(const Node *root)
    {
      Node *newnode;
      newnode=root;
      if(newnode!=NULL)
      {
         ShowTree(newnode->left);
         printf("%s--%c--%s--%s--%s--%s.
    ",root->person->name,root->person->sex, 
                  root->person->bir_year,root->person->bir_month,
              root->person->bir_day,root->person->qq);
         ShowTree(newnode->right);
      }
    }
    
    //查找树中有无指定姓名
    //若有返回1,若无返回0
    int SeekName(char name[20],const Node *root)
    {
       Node *pnode;
       if(root==NULL)
          return 0;
       pnode=root;
    
       while(pnode!=NULL)
       {  
          if(strcmp(name,pnode->person->name)<0)
          {
         pnode=pnode->left;
          }
          else if(strcmp(name,pnode->person->name)>0)
          {
         pnode=pnode->right;
          }
          else
             return 1;
       }
       return 0;
    }
    
    
    void ChoiceDel(Tree *ptree)
    {
      Node *nodef,*nodec;
      char namex[20];
      printf("please input the name:
    ");
      scanf("%s",namex);
      if(SeekName(namex,ptree->root)==0)
      {
        printf("the person %s is not exist!
    ",namex);
      }
      else
      {
        nodec=ptree->root;
        nodef=NULL;
        while(nodec!=NULL)
        {
           if(strcmp(namex,nodec->person->name)<0)
           {
          nodef=nodec;
          nodec=nodec->left;
           }
           else if(strcmp(namex,nodec->person->name)>0)
           {
          nodef=nodec;
          nodec=nodec->right;
           }
           else
          break;
         }//找到该节点及其父节点
         if(nodef==NULL)
              DeleteNode(&ptree->root);
         else if(nodef->left==nodec)
              DeleteNode(&nodef->left);
         else 
              DeleteNode(&nodef->right);
         ptree->numbers--;
         printf("--------%s is deleted!---------
    ",namex);
         
       }
    }
    
    //删除结点函数,参数如何描述?
    //删除操作后被删除结点的父节点的“指向被删结点的指针成员”要重新赋值
    //所以要用指向“父节点指针成员”的指针去描述
    //而父节点指针成员本身是一个Node*指针型,所以参数类型为Node **
    //注意:这里的ptr是指向父节点指针成员(指向被删结点)的指针类型
    //*ptr描述的是父节点中指向被删结点的指针成员,也即被删结点的地址指针类型
    //**ptr则是描述被删除的结点类型
    void DeleteNode(Node **ptr)
    {
      Node *temp;
    //*ptr为被删结点父节点的指针成员,该成员指向被删结点,
    //(*ptr)->left即指向被删结点的左子节点
    //若其左子节点为空,将其右子节点链接到父节点原先指向被删结点的指针成员
      if((*ptr)->left==NULL)   
      {
        temp=*ptr;
        *ptr=(*ptr)->right;
        free(temp);
      }
    //若其右子节点为空,将其左子节点链接到父节点原先指向被删结点的指针成员
      else if((*ptr)->right==NULL)
      {
        temp=*ptr;
        *ptr=(*ptr)->left;
        free(temp);
      }
      else  //被删除结点有两个子结点
      {
        for(temp=(*ptr)->left;temp->right!=NULL;temp=temp->right)
            continue;
        temp->right=(*ptr)->right;
        temp=*ptr;
        *ptr=(*ptr)->left;
        free(temp);
      }
    } 
    
    void Choicefind(Tree *ptree)
    {
      Node *nodef,*nodec;
      char namex[20];
      printf("please input the name:
    ");
      scanf("%s",namex);
      if(SeekName(namex,ptree->root)==0)
      {
        printf("the person %s is not exist!
    ",namex);
      }
      else
      {
        nodec=ptree->root;
        nodef=NULL;
        while(nodec!=NULL)
        {
           if(strcmp(namex,nodec->person->name)<0)
           {
          nodef=nodec;
          nodec=nodec->left;
           }
           else if(strcmp(namex,nodec->person->name)>0)
           {
          nodef=nodec;
          nodec=nodec->right;
           }
           else
          break;
         }//找到该节点及其父节点
         printf("the person:%s information is followed:
    ");
         printf("name:%s
    ",nodec->person->name);
         printf("sex:%c
    ",nodec->person->sex);
         printf("bir_year:%s
    ",nodec->person->bir_year);
         printf("bir_month:%s
    ",nodec->person->bir_month);
         printf("bir_day:%s
    ",nodec->person->bir_day);
         printf("qq:%s
    ",nodec->person->qq);
       }
       printf("input any key to continue...
    ");
       getch();
    } 
    
    
    void Choicemod(Tree *ptree)
    {
      Node *nodef,*nodec;
      char namex[20];
      char ch;
      printf("please input the name:
    ");
      scanf("%s",namex);
      if(SeekName(namex,ptree->root)==0)
      {
        printf("the person %s is not exist!
    ",namex);
      }
      else
      {
        nodec=ptree->root;
        nodef=NULL;
        while(nodec!=NULL)
        {
           if(strcmp(namex,nodec->person->name)<0)
           {
          nodef=nodec;
          nodec=nodec->left;
           }
           else if(strcmp(namex,nodec->person->name)>0)
           {
          nodef=nodec;
          nodec=nodec->right;
           }
           else
          break;
         }//找到该节点及其父节点
         printf("--------------------Please choose--------------------
    ");
         printf("a)----------modify name----%s
    ",nodec->person->name);
         printf("b)----------modify sex----%c
    ",nodec->person->sex);
         printf("c)----------modify bir_year----%s
    ",nodec->person->bir_year);
         printf("d)----------modify bir_month----%s
    ",nodec->person->bir_month);
         printf("e)----------modify bir_day----%s
    ",nodec->person->bir_day);
         printf("f)----------modify qq----%s
    ",nodec->person->qq);
         printf("q)---------------quit to upperlevel------------------
    ");
       
         ch=getch();
         printf("your choice is %c.
    ",ch);
         while(getchar()!='
    ') continue;
         while(ch!='q')
         {
           while(ch!='a'&&ch!='b'&&ch!='c'&&ch!='d'&&ch!='e'&&ch!='f'&&ch!='q')
           {
          printf("input a or b or c or d or e or f or q.
    "); 
              ch=getchar();
              printf("your choice is %c.
    ",ch);
           }
           switch(ch)
           {
        case 'a':
                printf("input %s new name:",nodec->person->name);
                scanf("%s",nodec->person->name);
                while(getchar()!='
    ') continue;
                break;
        case 'b':
                printf("input %s new sex:",nodec->person->name);
                scanf("%c",&(nodec->person->sex));
                while(getchar()!='
    ') continue;
                break;
        case 'c':
                printf("input %s new bir_year:",nodec->person->name);
                scanf("%s",nodec->person->bir_year);
                while(getchar()!='
    ') continue;
                break;
        case 'd':
                printf("input %s new bir_month:",nodec->person->name);
                scanf("%s",nodec->person->bir_month);
                while(getchar()!='
    ') continue;
                break;
        case 'e':
                printf("input %s new bir_day:",nodec->person->name);
                scanf("%s",nodec->person->bir_day);
                while(getchar()!='
    ') continue;
                break;
        case 'f':
                printf("input %s new QQ:",nodec->person->name);
                scanf("%s",nodec->person->qq);
                while(getchar()!='
    ') continue;
                break;
        case 'q':
                break;
           }
           if(ch!='q')
           {
         printf("--------------------Please choose--------------------
    ");
         printf("a)----------modify name----%s
    ",nodec->person->name);
         printf("b)----------modify sex----%c
    ",nodec->person->sex);
         printf("c)----------modify bir_year----%s
    ",nodec->person->bir_year);
         printf("d)----------modify bir_month----%s
    ",nodec->person->bir_month);
         printf("e)----------modify bir_day----%s
    ",nodec->person->bir_day);
         printf("f)----------modify qq----%s
    ",nodec->person->qq);
         printf("q)---------------quit to upperlevel------------------
    ");
             ch=getch();
             printf("your choice is %c.
    ",ch);
           }
           
           
         }
      }
    } 
    
    
    void NodeWrite(const Node *node)
    {
       FILE *fp;
       fp=fopen("c.txt","a");
       fprintf(fp,"%s",node->person->name);
       putc('-',fp);
       putc(node->person->sex,fp);
       putc('-',fp);
       fprintf(fp,"%s",node->person->bir_year);
       putc('-',fp);
       fprintf(fp,"%s",node->person->bir_month);
       putc('-',fp);
       fprintf(fp,"%s",node->person->bir_day);
       putc('-',fp);
       fprintf(fp,"%s",node->person->qq);
       putc('-',fp);
       putc('
    ',fp);
       fclose(fp);
    }
    
    void TreeWrite(const Node *root)
    {
       Node *pnode;
       pnode=root;
       if(pnode!=NULL)
       {
         TreeWrite(pnode->left);
         NodeWrite(pnode);
         TreeWrite(pnode->right);
       }
    }
    
    
    int main(void)
    {
    //变量设置区----------------------------------------
      Tree *ctree;
      char ch;
    //变量设置结束--------------------------------------
     
    //程序信息区-----------------------------------------
      printf("*******************************************************************
    ");
      printf("-----------------------------Address Book--------------------------
    ");
      printf("------------------------------Version1.0---------------------------
    ");
      printf("-----------------------------By TSEMBRACE--------------------------
    ");
      printf("*******************************************************************
    ");  
    //程序信息结束---------------------------------------
    
    //初始化数
      IniTree(ctree);
    
    //主操作界面区---------------------------------------
      ShowMainInterface();
      
      ch=getch();
      while(ch!='q')
      {
        while((ch!='a')&&(ch!='b')&&(ch!='c')&&(ch!='d')&&(ch!='e'))
        {
           printf("choose a or b or c or d or e or q!
    ");
           ch=getch();
           if(ch=='q')
         break;
        }
           
        
        switch(ch)
        {
          case 'a':
             if(ctree->root==NULL)
                printf("-----------There is no information.------------
    ");
         else
         {printf("---------My Address List is followed:---------
    ");
          ShowTree(ctree->root);
          printf("------------------My Address List end-------------------
    ");
             }
             printf("Total number is %d.
    ",ctree->numbers);
             ShowMainInterface();
             printf("please choose:
    ");
             ch=getch();  
             printf("your choose is:%c
    ",ch);     
         break;
          case 'b':ChoiceAdd(ctree);ShowMainInterface();
             printf("please choose:
    ");
             ch=getch();
             printf("your choose is:%c
    ",ch);        
         break;
          case 'c':Choicemod(ctree);ShowMainInterface();
             printf("please choose:
    ");
             ch=getch(); 
             printf("your choose is:%c
    ",ch);       
         break;
          case 'd':ChoiceDel(ctree);ShowMainInterface();
             printf("please choose:
    ");
             ch=getch();
             printf("your choose is:%c
    ",ch);        
         break;
          case 'e':Choicefind(ctree);ShowMainInterface();
             printf("please choose:
    ");
             ch=getch();
             printf("your choose is:%c
    ",ch); 
         break; 
          case 'q':
             printf("your choose is:q
    "); 
         break;
         }
      }
      
      TreeWrite(ctree->root);
      printf("GoodBye!
    input any key to quit.");
         
    //主操作界面结束-------------------------------------
    
      getch();
      return 0;
    }
  • 相关阅读:
    线程安全
    MS.NET 平台调用、托管DLL、非托管DLL简介
    在 C# 中通过 P/Invoke 调用Win32 DLL(非托管)
    控制发散思维
    如何创建和使用 C# DLL(受托管)
    Creating a Manager for Multiple Threads_翻译
    Sending Operations to Multiple Threads_翻译
    软件工程概论1
    xna4.0读书笔记 1.xna的基本结构
    Windows Phone SDK 7.1 简体中文版下载
  • 原文地址:https://www.cnblogs.com/tsembrace/p/3197424.html
Copyright © 2011-2022 走看看