1. 程式人生 > >C語言檔案讀取和單鏈表的新增、刪除和排序等操作例項

C語言檔案讀取和單鏈表的新增、刪除和排序等操作例項

/*
1、從文字檔案中匯入班級學生資訊:學號、姓名、性別、籍貫
2、將學號重複的刪除
3、顯示匯入的學生資訊
4、按學號、姓名、性別、籍貫相等和不相等查詢
5、多次查詢
6、查詢結果寫入檔案
7、VC++6.0編譯通過
//以下程式碼存為main.cpp
*/

#include <stdio.h>
#include <malloc.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>


#define CLRSCR system("cls")
#define PRINT_TITLE "\n序號\t學號\t\t姓名\t性別 \t籍貫\n"
#define PRINT_FORMAT "%d\t%s\t%s\t%s\t%s\n",i,p->stu.num,p->stu.name,p->stu.sex,p->stu.hometown
#define WRITE_FORMAT "%s\t%s\t%s\t%s\n",p->stu.num,p->stu.name,p->stu.sex,p->stu.hometown
#define READ_FORMAT "%s %s %s %s",&p->stu.num,&p->stu.name,&p->stu.sex,&p->stu.hometown

//定義學生結構體
struct student

 char num[9];
 char    name[7];//三個漢字長度為6個位元組,如果不多定義一個位元組來存放字串結束符'\0',當輸出name時會把sex和hometown也輸出
 char sex[3];
 char hometown[7];

};

//定義單鏈表結點
typedef struct listnode 
{   
 struct student stu;
 struct listnode *next;
}node;

int MySelect(node * head,node *temp)   //返回查詢到符合條件的專案數

 int equal,N;
 char CHAR[10];


 printf("----------------------------------------------\n\n");
 printf("查詢模式:1是相等查詢,0是不相等查詢\n");
 printf("列名編號:1是學號,2是姓名,3是性別,4是籍貫\n");
 printf("\n--------------------------------------------\n");

 do
 {
 printf("\n選擇查詢模式:");//用scanf時輸入字母會錯誤 改用getche,不用scanf
 equal=getche();
 if((equal!='1')&&(equal!='0'))
  printf("\n\t輸入錯誤\n");
 }
 while((equal!='1')&&(equal!='0'));
 equal=equal-48;


 
 do
 {
 printf("\n輸入列名編號:");
 N=getche();
 if(N!='1'&&N!='2'&&N!='3'&&N!='4')
  printf("\n\t輸入錯誤\n");
 }
 while(N!='1'&&N!='2'&&N!='3'&&N!='4');
 switch(N)
 {
 case '1': N=0;break;
 case '2': N=9;break;
 case '3': N=16;break;
 case '4': N=19;break;
 }

 printf("\n輸入關鍵字:");
 scanf("%s",CHAR);

 int  i=0,flag;
 node *p,*tp=temp;
 p=head->next;
 
 while (NULL!=p)
 { 
  flag=strcmp((char *)p+N,CHAR);
  if((abs(flag)+equal)==1)//當equal為1時是相等查詢,為0時是不相等查詢
  { 
   node *end;
   end = (node *)malloc(sizeof(node));
   tp->next=end;
   tp=end;
   tp->next=NULL;
   tp->stu=p->stu;
  
   if(i==0)
    printf (PRINT_TITLE);
   i++;
   printf(PRINT_FORMAT);


  }
  p=p->next;

 }

 if(i==0)
  printf("\n\t沒有查詢到符合條件的資訊\n");

return i;
}

void InsertSort(node *head)//學號從小到大排序
{
 node *p,*q,*r,*u;
    p=head->next; 
 head->next=NULL;
    while(p!=NULL)
    {
  r=head; 
  q=head->next;
        
  while(q!=NULL&& strcmp(q->stu.num,p->stu.num)<0) //成立則基點向後移
  {
   r=q;
   q=q->next;
  }
  u=p->next;
  p->next=r->next;   //p->stu.num比q->stu.num小,放到q->stu.num前面
  r->next=p; 

  p=u;//下一上節點與基點進行比較
 }
}

void CheckNum(node *head)
{
 /*刪除學號重複的條目*/
  node *release,*p;
  p=head->next;
  int m=0;
  while(NULL!=p->next)
  {
   node *p2=p;
   
   while(NULL!=p2->next)
   {
    if(0==strcmp(p->stu.num,p2->next->stu.num))
    { m++;
     if(m==1)
     printf("\t\t以下條目因學號與前面的資訊衝突而沒有匯入\n");

     printf ("%d\t%s\t%s\t%s\t%s\n",m,p2->next->stu.num,p2->next->stu.name,\
     p2->next->stu.sex,p2->next->stu.hometown);

     release=p2->next;
     p2->next=p2->next->next;
     free(release);    
    }
    p2=p2->next;
   }

   p=p->next;
  }


}


void FscanfFromFile(node *head)

 char file[15];
 printf("輸入待匯入的檔名:");
 scanf("%s",file);

 FILE *fp;
 if((fp=fopen(file,"r"))==NULL)
 {
  printf("\n\t檔案開啟失敗,按任意鍵退出\n");
  getch();
  exit(0);
 }
 
 node *p=head;

 while(!feof(fp))
 { 
  node *end;  
  end = (node *)malloc(sizeof(node));
  p->next=end;
  p=end;
  p->next=NULL;
 
  fscanf(fp,READ_FORMAT);
  
 }
  printf("\n\t資訊匯入成功\n");
  
  fclose(fp);

 void CheckNum(node *head);
 void InsertSort(node *head);
 CheckNum(head);
 InsertSort(head);

}

void ShowList(node *head)//帶頭結點的連結串列
{
 node *p=head->next;
 int i=0;
 printf (PRINT_TITLE);
 while(NULL!=p )//*****************NULL!=p 不是NULL!=p->next
 { i++;
  printf (PRINT_FORMAT);
  p=p->next;
 }

}

void FprintfToFile(node *head)
{
 char file[15];

 printf("\n輸入要寫入的檔名:");
 scanf("%s",file);

 FILE *fp;
 if((fp=fopen(file,"w+"))==NULL)
 {
  printf("\n\t檔案建立失敗\n");

  exit(0);
 }
 node *p=head->next;
 while(NULL!=p)
 { 
  if(p->next==NULL)//不要最後一行的回車,這樣的話匯入該檔案時就不會有末尾的亂碼
   fprintf(fp,"%s\t%s\t%s\t%s",p->stu.num,p->stu.name,p->stu.sex,p->stu.hometown);
  else
   fprintf(fp,WRITE_FORMAT);
  p=p->next;
 }
 fclose(fp);
 printf("\n\t資料寫入成功\n",file);//printf輸出雙引號要用轉義字\"

}


node *ClearList(node *head)
{
 node *p=head->next;
 while(NULL!=p)
 {
  node *tp=p->next;
  free(p);
  p=tp;
 }
 return head->next=NULL;

}

int AddStu(node *head)
{
 node *p,*p2=head,*p3;
 p=(node *)malloc(sizeof(node));
 printf("依次輸入學生的學號、姓名、性別和籍貫(用空格隔開):\n");
 scanf("%s %s %s %s",p->stu.num,p->stu.name,p->stu.sex,p->stu.hometown);
 
 int flag=0;
 while(NULL!=p2->next)
 { /*找出第一個比新學生的學號大的位置,將新資訊放在它前面*/
  if((flag=strcmp(p->stu.num,p2->next->stu.num))<0)
  {
   p3=p2->next;
   p2->next=p;
   p->next=p3;
   break;//*******
  }
  
  p2=p2->next;
 }

 /*如果新新增學生的學號比已有的都大,放置最末尾*/
 if(flag>0)
 {
  p2->next=p;
  p->next=NULL;
 }
 void CheckNum(node *head);
 CheckNum(head);

 printf("資訊新增成功\n");
 printf("\t按任意鍵返回\n");
 getche(); 
 


 return 1;
}


int DeleteByNum(node *head)
{ char num[9];
 int flag=1;
 node *p=head,*p2;
 printf("輸入要刪除資訊的學號:");
 scanf("%s",num);
 while(NULL!=p->next)
 {
  if((flag=strcmp(p->next->stu.num,num))==0)
  {
   p2=p->next;
   p->next=p->next->next;
   free(p2);
   printf("刪除成功\n");
   break;//***************   
  }
  p=p->next;
 }

 if(flag!=0)
  printf("你輸入的學號不存在\n");
 printf("\t按任意鍵返回\n");
 getche();
  

 return 1;
}


int main()
{
 
    node *head;
 int i=0;
 head = (node *)malloc(sizeof(node));
 strcpy(head->stu.num," ");
 strcpy(head->stu.hometown," ");
 strcpy(head->stu.name," ");
 strcpy(head->stu.sex," ");
 node *temp= (node *)malloc(sizeof(node));//儲存查詢結果的頭結點

  printf("歡迎使用\n");
  printf("\n----------------------------------------------\n");


  FscanfFromFile(head);


 char charget;

 do
 {
  printf("\n----------------------------------------------\n");
  printf("\n[1]資訊顯示\n");
  printf("[2]資訊查詢\n");
  printf("[3]新增資訊\n");
  printf("[4]刪除資訊\n");
  printf("[5]退出程式\n");

  do
  {
  charget=getch();
  }
  while((charget!='1')&&(charget!='2')&&(charget!='3')&&(charget!='4')&&(charget!='5'));

  switch(charget)
  {
  case '1': ShowList(head);
     printf("\n按任意鍵顯示上層操作選單\n");
     getch();
     break;
  case '2': if(0!=MySelect(head,temp))//查詢結束不為空則進行下面的操作,為空則返回上層選單
     {

      char charget2;
      do
      {
       printf("\n[1]在此基礎上繼續查詢\n");
       printf("[2]將查詢結果寫入檔案\n");
       printf("[3]退出本次查詢\n");
       
       
       do
       {
        charget2=getch();
       }
       while((charget2!='1')&&(charget2!='2')&&(charget2!='3'));

       switch(charget2)
       {
       case '1': if(0==MySelect(temp,temp))
          { 
           printf("\n按任意鍵結束本次查詢\n");
           getch();
           charget2='3'; 
          }
          break;

       case '2': FprintfToFile(temp);
          charget2='3';//資料寫入後,自動結束本次查詢
          break;
       case '3': ClearList(temp);//結束查詢,釋放暫存查詢結果的連結串列
          break;
       

       }//end switch,結束本次查詢

      }
      while(charget2!='3');//如果charget2也用charget的話,在查詢中按鍵3會直接退出程式
     }//end if
     break;
  case '3': AddStu(head);break;
  case '4': DeleteByNum(head);break;
     
  }//end switch,結束操作

 }
 while(charget!='5');

return 0;
}
//以下資料存為class.txt
20074879 耿同學  男 江西

20077502 王同學 男 四川
20077508 肖同學 男 四川
20077524 王同學 男 四川
20077554 謝同學 男 四川


20067049 李同學 女  四川
20067054 王同學 男  四川
20067055 張同學 男 四川
20067061 劉同學 男 四川
   
20067049 楊同學 女  四川
   
20071020 趙同學 男 四川
20071080 周同學 女 四川
20071262 吳同學 女 四川
20072672 徐同學 女 四川
20072993 孫同學 女 黑龍江
20073728 朱同學 男 四川
20074864 馬同學 女 北京
20074865 衚衕學 女 甘肅
20074866 郭同學 女 廣東
20074867 林同學 女 廣西
20074868 何同學 女 陝西
20074869 高同學 女 四川
20074870 樑同學 女 四川
20074871 鄭同學 女 四川
20074872 羅同學 女  四川
20074873 宋同學 女 四川
20074874 謝同學 男 福建
20074876 唐同學 男 黑龍江
20074877 韓同學 男 湖北
20074878 曹同學 男 湖南
20074879 許同學 男 江西
20074880 鄧同學 男 遼寧
20074881 傅同學 男 寧夏
20074882 馮同學 男 山東
20074883 曾同學 男 四川
20074884 程同學 男 四川
20074885 蔡同學 男 四川
20074886 彭同學 男 四川
20074887 藩同學 男 四川
20074888 袁同學 男 四川
20074889 於同學 男 四川
20074890 董同學 男 四川
20074891 餘同學 男 四川
20074892 蘇同學 男 四川
20074893 葉同學 男 四川
20074894 呂同學 男 四川
20074895 魏同學 男 四川
20074896 蔣同學 男 四川
20074897 田同學 男 四川
20074898 杜同學 男 四川
20074899 丁同學 男 天津
20074900 沈同學 男 浙江
20075235 姜同學 男 四川
20075658 唐同學 男 四川
20076057 王同學 女 四川
20076060 穆同學 男 四川
20076098 陳同學 女 四川
20076101 王同學 女 四川
20076120 黃同學 女 四川
20077391 魏同學 男 四川
20077499 丁同學 男 四川