#include
#include
#include
#include
#include
struct student {
       char name[30] ;
       int stno ;
       int unit ;
       float ave ;
} ainfo ;

int menu_select(void);
void enter();
void report();
void quick_file(FILE *pf,int left, int right);
void swap_all_fields(FILE *fp, long i , long j);
char *get_name(FILE *fp, long rec) ;
void main()
{
   FILE *fp ;
   long int x;
   int handle, y;
   if((fp = fopen("mlist", "a+b")) == NULL) {
       printf("\cannot open file .");
       getch();
       exit(1) ;
   }
   for(;;) {
     clrscr();
     switch(menu_select()) {
    case 1: enter(); break;
    case 2:
       if((fp = fopen("mlist", "r+b")) == NULL) {
   printf("\cannot open file .");
   getch();
   exit(1) ;
       }
       handle = fileno(fp);
      x = filelength(handle);
      y = x / (sizeof(struct student));
      quick_file(fp, 0, y - 1);
      fclose(fp);
      break;
    case 3: report(); break;
    case 4: exit(1);
     } //end of switch
   }  //end of for
}
//****************
void quick_file(FILE *fp, int left, int right)
{
    long int i, j;
    char x[10];
    i = left;
    j = right;
    strcpy(x, get_name(fp, (long)(i + j) / 2));
    do {
       while(strcmp(get_name(fp, i), x) < 0
      && i< right) i ++ ;
       while(strcmp(get_name(fp, j), x) > 0
      && i < right) j -- ;
       if(i <= j) {
   swap_all_fields(fp, i, j) ;
   i ++ ;
   j -- ;
       }
     } while(i <= j) ;
     if(left < j) quick_file(fp, left, (int) j) ;
     if(i < right)  quick_file(fp,(int) i,right);
}
//*********************
void swap_all_fields(FILE *fp, long i, long j)
{
    char a[sizeof(ainfo)], b[sizeof(ainfo)];
    fseek(fp, sizeof(ainfo) * i, 0) ;
    fread(a,  sizeof(ainfo),  1, fp) ;
    fseek(fp, sizeof(ainfo) * j, 0) ;
    fread(b,  sizeof(ainfo),  1, fp) ;
    fseek(fp, sizeof(ainfo) * j, 0) ;
    fwrite(a, sizeof(ainfo),  1, fp) ;
    fseek(fp, sizeof(ainfo) * i, 0) ;
    fwrite(b, sizeof(ainfo),  1, fp) ;
}
//*****************
char *get_name(FILE *fp, long rec)
{
    struct student *p ;
    p = &ainfo ;
    fseek(fp, rec * sizeof(ainfo), 0);
    fread(p, sizeof(ainfo), 1, fp) ;
    return(ainfo.name) ;
}
//**********************
int menu_select(void)
{
      char s[10] ;
      int c ;
      clrscr() ;
      gotoxy(29, 6);
      printf("1) << enter a recorde >>");
      gotoxy(29, 8);
      printf("2) << sort the file >>");
      gotoxy(29, 10);
      printf("3) << list  the file >>");
      gotoxy(29, 12);
      printf("4) <<      Quit     >>");
      do {
   gotoxy(24, 15) ;
   printf(" Please enter your choice(1-4):");
   gets(s) ;
   c = atoi(s) ;
      } while(c < 0 || c > 4) ;
      return (c);
}

//****************************
void enter()
{
   int slot ;
   char numstr[10] ;
     FILE *fp;
   if((fp = fopen("mlist", "a+b")) == NULL) {
       printf("\cannot open file .");
       getch();
       exit(1) ;
   }
  gotoxy(5, 17) ;
  printf("enter name:") ;
  gets(ainfo.name);
  gotoxy(40, 17) ;
  printf("enter stno:") ;

  gets(numstr);
  ainfo.stno = atoi(numstr);
  gotoxy(5, 19) ;
  printf("enter unit:") ;
  gets(numstr);
  ainfo.unit = atoi(numstr);

  gotoxy(40, 19) ;
  printf("enter average:") ;
  gets(numstr);
  ainfo.ave = atof(numstr);
  fwrite(&ainfo, sizeof(struct student), 1, fp);
  fclose(fp);
}
//***********
void report()
{
     register  int t ;
     int r = 0 ;
     FILE *fp;
     if((fp = fopen("mlist", "r+b")) == NULL) {
       printf("\cannot open file .");
       getch();
       exit(1) ;
     }
     clrscr() ;
     gotoxy(20, 2) ;
     printf(" << all information in list are:>>") ;
     gotoxy(13, 3) ;
     printf("**********************");
     printf("*******************") ;
     gotoxy(10, 4);
     printf("     name      stno          unit      average");
     gotoxy(10, 5);
     printf("   ________    _______      ______      ______");
     fread(&ainfo, sizeof(struct student), 1, fp);
     while(!feof(fp)) {
      gotoxy(14, 6 + r) ;
      printf("%s ", ainfo.name);
      gotoxy(26, 6 + r) ;
      printf("%d ", ainfo.stno);
      gotoxy(40, 6 + r) ;
      printf("%d ", ainfo.unit);
      gotoxy(52, 6 + r) ;
      printf("%.2f ", ainfo.ave);
      r++ ;
      fread(&ainfo, sizeof(struct student), 1, fp);
     }
     gotoxy(13, 6 + r) ;
     printf("********************");
     printf("*********************");
     gotoxy(27, 7 + r) ;
     printf("press any key to continue");
     fclose(fp);
     getch() ;
}