#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define SIZE 200
#define BUFF 10000 
#define MODBUFFER 10
/*Записная книга*/
int modecorrect(char *str); /*Прототипы*/ /*Проверка упр. строки*/
void getdata(unsigned char *field, FILE *file); /*Получение данных формы*/
unsigned int fillStruct(FILE *file, struct person bigArray[], unsigned int arraySize);
int qsort(struct person *left, int allnumber, int (*compare)(void *A, void *B));
int compare(char p[], char q[]);
/*заполнение структуры из файла*/
struct person{                            /*Структура записи*/
  unsigned char name[12];
  unsigned char surname[12];
  unsigned char number[20];
};
int main(void)
{
FILE *MyBook;
size_t i, count; //for structure
unsigned int Size = 200;
struct person NewData;
struct person Contacts[SIZE]; /*Массив структур*/
unsigned char *out = malloc(BUFF * sizeof(unsigned char)); 
/*указатель в файле при выводе и сортировке*/
unsigned char *pname    = NewData.name;     /*используются в первичном заполнении*/      
unsigned char *psurname = NewData.surname;
unsigned char *pnumber  = NewData.number;
unsigned char *mode     = malloc(MODBUFFER * sizeof(unsigned char)); /* Read or Add */
unsigned char *answer   = malloc( 4 * sizeof(unsigned char));        /* YES / NO */
printf("MyBook 1.0\nEnglish language is used(!) \nChoose your mode:"); 
while(1){ //// !!!!!Начало общего зацикливания
printf("\nInput \"Read\" or \"Add\"\n");
gets(mode);
printf("\n");
if(!strcmp(mode,"Add")) /*Режим добавления*/
{
if((MyBook = fopen("MyBook.txt", "a+")) == NULL)// 
printf("Writing MyBook.txt error");
printf("Please, input new data\nto stop press <Enter>\n");
while(1){//////////////////
printf("Name: ");
 getdata(pname, MyBook);
if(!strcmp(pname, ""))
 break;
fprintf(MyBook, " ");
printf("Surname: ");
 getdata(psurname, MyBook);
fprintf(MyBook, " ");
printf("Number: ");
 getdata(pnumber, MyBook);
fprintf(MyBook, "\n");
}//////////////////////////
fclose(MyBook);
}
/* Режим чтения и сортировки */
if(!strcmp(mode,"Read"))
{
if((MyBook = fopen("MyBook.txt", "r")) == NULL) 
printf("Reading MyBook.txt error");
do{
 fscanf(MyBook, "%c" , out);
 putchar(*out);
}while(!feof(MyBook));
do{
 printf("\n Alphabet sort? Input \"Yes\" or \"No\" ");
 gets(answer);
}while(strcmp(answer, "Yes") && strcmp(answer, "No"));
if(!strcmp(answer, "Yes"))
{
        rewind(MyBook); 
    count = fillStruct(MyBook, Contacts, SIZE); 
        //--------------------------------Q_SORT------------------------------------------//
    qsort(Contacts, count , compare);
        //--------------------------------------------------------------------------------//
        for (i = 0; i < count; ++i)                // вывод отсортированной структуры
         printf("%s %s %s\n", Contacts[i].name, Contacts[i].surname, Contacts[i].number );
}
fclose(MyBook);
}
} ////!!!!
return 0;
}
/////////////////////////////////////////////////////////////////////////
int modecorrect(char *str)  /* small functions */
{
if(!strcmp(str, "Add") || !strcmp(str, "Read"))
 return 1;
return 0;
}
/////////////////////////////////////////////////////////////////////////
void getdata(unsigned char *field, FILE *file)
{
gets(field), fputs(field, file);
}
////////////////////// Сортировка по алфавиту  //////////////////////////
int qsort(struct person *left, int allnumber, int (*compare)(void *A, void *B))
{
        struct person *last, *right = left + allnumber - 1, *i;
        if (left >= right)
          return 1;
        if (!swap(left, left + (right-left)/2))
          return 0;
        last = left;
        for (i = left + 1; i <= right; ++i)
        {       
          if (compare(i, left))
                if (!swap(++last, i))
                  return 0;
        }
        if (!swap(left, last))
          return 0;
        qsort(left, last-left, compare);
        qsort(last+1, right-last, compare);
        return 1;
}
//........................................................//
int swap (struct person * A, struct person * B ) //меняет местами указатели на структурные переменные
{
  struct person *temp;
  if ((temp = (struct person *) malloc(sizeof(struct person))) == NULL)
        return 0; 
  *temp = *A;
  *A = *B;
  *B = *temp;
  free(temp);  
  return 1;
}
/////////////////////// Заполнение массива структур //////////////////////
unsigned int fillStruct(FILE *file, struct person bigArray[], unsigned int arraySize) 
{
    unsigned int index = 0;
    while((index < arraySize) && !feof(file)) 
        {
        fscanf(file,"%11s %11s %19s\n", bigArray[index].name, bigArray[index].surname, bigArray[index].number);
                ++index;
    }
    return index;
}
///////////////////////////Сравнение////////////////////////////// WORK
int compare(struct person *p, struct person *q)    //(p<q)? Сравнение двух строк
{
  return strcoll(p->name, q->name);
}