Сортировка за определенный период - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Подскажите, мучаюсь уже пару дней.. Нужно написать такой код, чтоб моя база делала вот такую функцию..

" Программа должна формировать отчет о постановке на учет машин за определенный период "

вывод на экран. Если нужно, скину весь проект. Спасибо)
////////////////////////////
#define MARKA 20
#define MODEL 20
#define NAME 60
#define S_NOMER 1
#define G_NOMER_CIFRI  1
#define G_NOMER_BUKVI  11
#define G_NOMER_UNIKAL 1
 
#define DAY 1
#define MON 1
#define YEAR 1
//////////////////////////////
typedef struct  
{
    char name[NAME];
    char marka[MARKA];
    char model[MODEL];
    int  s_nomer[S_NOMER];
    int  g_nomer_cifri[G_NOMER_CIFRI];
    char g_nomer_bukvi[G_NOMER_BUKVI];
    int  g_nomer_unikal[G_NOMER_UNIKAL];
    int  day[DAY];
    int  mon[MON];
    int  year[YEAR];
}baza;
//////////////////////////////
baza group[N] =
{
    {"ОЛЯ",        "Hummer",      "H2",            {940349},{1111},"OO",{2},{29},{03},{2011}},
    {"КАТЯ",       "Audi",           "Q7 Quattro",{954056},{7777},"АН",{2},{30},{04},{2012}},
    {"ПАША",      "BMW",          "X6",            {659323},{9339},"AA",{2},{01},{02},{2009}},
    {"САША",      "Alfa Romeo" , "155",          {485734},{2902},"AI",{2},{22},{11},{2013}},
    {"МАША",      "Peugeot",     "406",           {934224},{9000},"ВА",{2},{02},{04},{2011}},
    {"ДАША",      "Renault",      "Twingo",      {128420},{4234},"ВВ",{2},{21},{05},{2003}},
    {"ПЕТЯ",       "Audi",           "A4",            {994949},{6648},"ЕО",{2},{23},{03},{2006}},
    {"ГРИША",     "Volkswagen", "Passat B6" ,  {111234},{2332},"АВ",{2},{13},{11},{1999}},
    {"ЮЛЯ",        "Citroen",       "c3",            {223344},{8889},"AI",{2},{15},{12},{2012}},
    {"СВЕТА",      "Nissan",        "Micra",        {663505},{9304},"ОA",{2},{19},{03},{1992}}
};
 
//Вывод такой
static void print_stud(const baza *p)
{
    int j;
    printf("%-12s%-12s%-32s", p->marka, p->model, p->name);
 
    for(j=0; j< sizeof(p->s_nomer)/sizeof(p->s_nomer[0]); ++j)
    printf("%-12d",          p->s_nomer[j]);
 
    for(j=0; j< sizeof(p->g_nomer_cifri)/sizeof(p->g_nomer_cifri[0]) ; ++j)
    printf("%-5d",               p->g_nomer_cifri[j]);
 
    printf("%s", p->g_nomer_bukvi);
 
    for(j=0; j< sizeof(p->g_nomer_unikal)/sizeof(p->g_nomer_unikal[0]); ++j)
    printf("-%-5d",                p->g_nomer_unikal[j]);
////////date
    for(j=0; j< sizeof(p->day)/sizeof(p->day[0]); ++j)
        printf("%d",                p->day[j]);
    for(j=0; j< sizeof(p->mon)/sizeof(p->mon[0]); ++j)
        printf(".%d",                p->mon[j]);
    for(j=0; j< sizeof(p->year)/sizeof(p->year[0]); ++j)
        printf(".%d",                p->year[j]);
//////
 
    printf("\n");
}

Консоль

Решение задачи: «Сортировка за определенный период»

textual
Листинг программы
#include <stdio.h>  //Библиотека функций ввода и вывода
#include <string.h> //Библиотека функций обработки строк
#include <stdlib.h> //Библиотека стандартных функций
typedef struct{      //Описание структуры для хранения даты
  unsigned dd:5,mm:4,yy:14;//с использованием битовых полей
} DATE;
typedef struct{      //Описание структуры для хранения
  char fio[3][16];   //информации об абоненте
  int number;
  DATE date;
} ABONENT;
//Функция загрузки списка из файла
int LoadList(const char *,ABONENT **,int*);
void Sort(ABONENT*,int);             //Функция сортировки
void Search(ABONENT *,int,DATE,DATE);//Функция поиска
int InputDate(DATE *);               //Функция ввода даты
int CmpDate(DATE,DATE);              //Функция сранения дат
/* ---------- Главная функция программы main ----------- */
int main(int argc, char *argv[])
{
  //Если имя исходного файла не указано, то выход
  if(argc < 2) {puts("Не указано имя файла!"); return 0;}
  ABONENT *list = NULL; //Указатель на список записей
  int num = 0;          //Количество записей в списке
  //Вызов функции загрузки списка и анализ ее результата
  switch(LoadList(argv[1],&list,&num)){
    case 1: {puts("Невозможно открыть файл!"); return 0;}
    case 2: {puts("Недостаточно памяти!"); return 0;}
  }
  Sort(list,num);          //Сортировка списка по дате
  DATE date_from, date_to; //Переменные для хранения дат
  do{  //Ввод дат с которой и по какую осуществлять поиск
    do           //Ввод даты с которой осуществляется поиск
      printf("Начальная дата: ");//с проверкой корректного
    while(InputDate(&date_from)); //ввода
    do        //Ввод даты по которую осуществляется поиск
      printf("Конечная дата: ");//с проверкой корректного
    while(InputDate(&date_to)); //ввода
    //Если даты введены в хронологическом порядке, то выход
    if(CmpDate(date_from,date_to) <= 0) break;   //из цикла
    puts("Даты введены некорректно!");//Сообщение об ошибке
  }while(1);
  Search(list,num,date_from,date_to); //Поиск в списке
  free(list);  //Удаление списка
  return 0;    //Выход
}
/* ------------ Функция загрузки списка -------------------
Параметры: name - имя файла,
           list - указатель на список (по ссылке),
           num  - количество записей в списке (по ссылке)
Возвращаемое значение: 0 - успешное завершение,
                       1 - некорректное имя файла
                       2 - нехватка динамической памяти
-------------------------------------------------------- */
int LoadList(const char *name, ABONENT **list, int *num)
{
  FILE *file = fopen(name,"rb"); //Открытие файла
  if(!file) return 1;   //Если открыть не удалось, то выход
  fseek(file,0,SEEK_END);   //Переход в конец файла
  //Определение количества записей в файле
  int cnt = ftell(file)/sizeof(ABONENT);
  fseek(file,0,SEEK_SET);   //Переход в начало файла
  //Выделение динамической памяти под список
  ABONENT *tmp = (ABONENT *)calloc(cnt,sizeof(ABONENT));
  //Если память не выделилась, то выход
  if(!tmp) {fclose(file); return 2;}
  fread(tmp,sizeof(ABONENT),cnt,file);   //Считывание даных
  fclose(file);                          //Закрытие файла
  *list = tmp; *num = cnt; //Установка переменных по ссылке
  return 0;  //Выход
}
/* --------- Функция поиска одной записи в списке ---------
Параметры: list   - указатель на список,
           num    - количество записей в списке,
           start  - номер записи, с которой начинать поиск,
           date_from - левая граница временного промежутка,
           date_to   - правая граница временного промежутка
Возвращаемое значение: -1 - запись не найдена,
                       ?0 - номер записи в списке.
Реализован алгоритм линейного поиска.
-------------------------------------------------------- */
int Find(ABONENT *list, int num, int start,
         DATE date_from, DATE date_to)
{
  for(int i=start;i<num;i++)
    if((CmpDate(list[i].date,date_from)>=0)&&
       (CmpDate(list[i].date,date_to)<=0))  return i;
  return -1;
}
/* --------- Функция поиска всех записей в списке ---------
Параметры: list   - указатель на список,
           num    - количество записей в списке,
           start  - номер записи, с которой начинать поиск,
           date_from - левая граница временного промежутка,
           date_to   - правая граница временного промежутка
-------------------------------------------------------- */
void Search(ABONENT *list, int num, DATE date_from,
            DATE date_to)
{
  char fname[50] = "";   //Имя файла для отчета
  for(int i=0;i<2;i++){  //Цикл на две итерации
    FILE *file = stdout; //Установка на стандартный вывод
    //Если это вторая итерация, то вывод в файл
    if(i == 1) file=fopen(fname,"w");
    //Если открыть файл не удалось, то выход
    if(!file) {puts("Невозможно создать файл!"); return;}
    int ind = -1; //Индекс найденной записи
    //Поиск записей в цикле, выход - если запись не найдена
    while((ind=Find(list,num,ind+1,date_from,date_to))!=-1)
      //Вывод найденной записи
      fprintf(file,"%-15s %-15s %-15s %7u %2u.%2u.%4u\n",
              list[ind].fio[0],  list[ind].fio[1],
              list[ind].fio[2],  list[ind].number,
              list[ind].date.dd, list[ind].date.mm,
              list[ind].date.yy
             );
    char ch = 'n'; //Символ для диалога с пользователем
    while(i==0){   //Если это первая итерация
      //Вопрос пользователю
      printf("Сохранить файл? (y/n): ");
      //Очистка буфера ввода и ввод символа
      fflush(stdin); scanf("%c",&ch);
      //Если ответ положительный
      if((ch == 'y')||(ch == 'Y')){
        printf("Имя файла: ");//Приглашение к вводу
        scanf("%s",fname);    //и ввод имени файла
        break;                //Выход из вложенного цикла
      }
      //Если ответ отрицательный, то выход
      if((ch == 'n')||(ch == 'N')) return;
    }
  }
}
/* ---- Функция ввода даты и проверки ее корректности -----
Параметр: date - структура дата, в которую осуществляется
          ввод (по ссылке)
Возвращаемое значение: 0 - дата введена корректно
                       1 - дата введена не корректно
-------------------------------------------------------- */
int InputDate(DATE *date)
{
  unsigned day,mon,year;  //Локальные переменные
  //Ввод значения в формате дд.мм.гггг.
  //Если ввод некорректный, то выход со значением 1
  if(scanf("%u.%u.%u",&day,&mon,&year) != 3) return 1;
  //Проверка корректности введенных значений
  if((day<1)||(day>31)||(mon<1)||(mon>12)||(year<1))
    return 1;
  //Проверка корректности ввода числа для месяцев, в
  //которых 30 дней и для февраля с учетом високосного года
  switch(mon){
    case 4: case 6: case 9: case 11: 
      if(day>30) return 1; else break;
    case 2: if(( (year%4)&&(day>28))||
               (!(year%4)&&(day>29))) return 1;
  }
  //Запись значений в структуру
  date->dd = day; date->mm = mon; date->yy = year;
  return 0; //Выход
}
/* ------------- Функция сравнения двух дат ---------------
Параметр: dt1 - первая дата,
          dt2 - вторая дата
Возвращаемое значение: 0 - даты равны,
                       1 - первая дата «больше»,
                      -1 - вторая дата «больше»
-------------------------------------------------------- */
int CmpDate(DATE dt1, DATE dt2)
{
  if(dt1.yy > dt2.yy) return 1;
    else if(dt1.yy < dt2.yy) return -1;
  if(dt1.mm > dt2.mm) return 1;
    else if(dt1.mm < dt2.mm) return -1;
  if(dt1.dd > dt2.dd) return 1;
    else if(dt1.dd < dt2.dd) return -1;
  return 0;
}
/* ------- Функция сортировки списка (внутренняя) ---------
Параметр: list - указатель на список,
          iLo  - нижний индекс,
          iHi  - верхний индекс.
Реализует алгоритм Хоара
-------------------------------------------------------- */
void QuickSort(ABONENT *list, int iLo, int iHi)
{
  int Lo = iLo, Hi = iHi;
  ABONENT mid = list[(Lo+Hi)/2];
  do{
    while(CmpDate(list[Lo].date,mid.date)<0) Lo++;
    while(CmpDate(list[Hi].date,mid.date)>0) Hi--;
    if(Lo <= Hi){
      ABONENT tmp = list[Lo];
      list[Lo] = list[Hi];
      list[Hi] = tmp;
      Lo++; Hi--; 
    }
  }while(Lo <= Hi);
  if(Hi > iLo) QuickSort(list,iLo,Hi);
  if(Lo < iHi) QuickSort(list,Lo,iHi);
}
/* -------- Функция сортировки списка (внешняя) -----------
Параметр: list - указатель на список,
          num  - количество элементов в списке
-------------------------------------------------------- */
void Sort(ABONENT *list,int num)
{
  QuickSort(list,0,num-1);
}

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

14   голосов , оценка 4 из 5
Похожие ответы