Сортировка за определенный период - 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); }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д