Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<stdio.h>
- #include<stdlib.h>
- #include<string.h>
- #include<stdbool.h>
- #include<errno.h>
- #include <ctype.h>
- typedef struct Measurements {
- int bust, waist, hip;
- } Measurements;
- typedef struct Contestant {
- char *firstName;
- char *lastName;
- char *interests;
- int age;
- int height;
- Measurements bwh;
- } Contestant;
- typedef struct Pair {
- int id;
- Contestant *con;
- } Pair;
- typedef struct Stack {
- Pair *data;
- int n;
- int size;
- int id;
- } Stack;
- void* myrealloc (void *ptr, size_t size) {
- void *res = realloc(ptr, size);
- if (res == NULL && size != 0) {
- fprintf(stderr, "myrealloc: unable to allocate %zd bytes\n", size);
- exit(EXIT_FAILURE); }
- return res;
- }
- /**/
- void* mymalloc (size_t size) {
- void *res = malloc(size);
- if (res == NULL) {
- fprintf(stderr, "mymalloc: unable to allocate %zd bytes\n ", size);
- exit(EXIT_FAILURE);
- }
- return res;
- }
- void printContestant (const struct Contestant *con) {
- printf("First Name: %s\n", con->firstName);
- printf("Last Name: %s\n", con->lastName);
- printf("Interests: %s\n", con->interests);
- printf("Age: %d\n", con->age);
- printf("Height: %d\n", con->height);
- printf("Measurments: %d %d %d\n", con->bwh.bust,con->bwh.waist,con->bwh.hip);
- }
- void destroyContestant (Contestant *con) {
- if (con == NULL) return;
- free(con->firstName);
- free(con->lastName);
- free(con->interests);
- free(con);
- }
- Stack* newStack ();
- void emptyStack (Stack *stack);
- void destroyStack (Stack *stack);
- void insertContestant (Stack *stack, Contestant *con);
- void removeContestant (Stack *stack, int ix);
- bool removeContestantId (Stack *stack, int id);
- Stack* newStack () {
- Stack *stack = (Stack *)mymalloc(sizeof(*stack));
- int initSize = 32;
- stack->data = (Pair *)mymalloc(sizeof(*stack->data) * initSize);
- stack->n = 0;
- stack->size = initSize;
- stack->id = 0;
- return stack;
- }
- void emptyStack (Stack *stack) {
- Pair *p = stack->data;
- int i,n = stack->n;
- for ( i = 0; i < n; i++) {
- destroyContestant(p[i].con);
- }
- stack->n = 0;
- }
- void destroyStack (Stack *stack) {
- if (stack == NULL) return;
- emptyStack(stack);
- free(stack->data);
- free(stack);
- }
- void insertContestant (Stack *stack, Contestant *con) {
- if (stack->size == stack->n) {
- stack->size *= 2;
- stack->data = (Pair*)myrealloc(stack->data, stack->size);
- }
- Pair *p = &stack->data[stack->n];
- p->id = stack->id;
- p->con = con;
- stack->n++;
- stack->id++;
- }
- void removeContestant (Stack *stack, int ix) {
- Contestant *con = stack->data[ix].con;
- destroyContestant(con);
- int i,n = stack->n;
- Pair *p = stack->data;
- for (i = ix + 1; i < n; i++) {
- p[i - 1] = p[i];
- }
- stack->n--;
- }
- bool removeContestantId (Stack *stack, int id) {
- bool flag = false;
- int ix = -1;
- Pair *p = stack->data;
- int i,n = stack->n;
- for (i = 0; i < n; i++) {
- if (p[i].id == id) {
- flag = true;
- ix = i;
- break;
- }
- }
- if (flag) removeContestant(stack, ix);
- return flag;
- }
- void printPair (const Pair *pair) {
- printf("ID: %d\n", pair->id);
- printContestant(pair->con);
- }
- void printContestantArray (Pair *xs, int n) {
- int i;
- for ( i = 0; i < n; i++) {
- printPair(xs + i);
- printf("\n");
- }
- }
- char* stripSpaces (const char *str) {
- const char *s = str;
- while (isspace(*s) && *s != '\0') s++;
- const char *e = str;
- while (*e != '\0') e++;
- if (e == s) {
- char *result = (char*)mymalloc(sizeof(*result));
- *result = '\0';
- return result;
- }
- e--;
- while (isspace(*e)) e--;
- int n = e - s + 1;
- char *result = (char*)mymalloc((n + 1) * sizeof(*result));
- memcpy(result, s, n);
- result[n] = '\0';
- return result;
- }
- bool hasEndl (const char *str) {
- while (*str != '\0' && *str != '\n') str++;
- return *str == '\n';
- }
- char* readLine (FILE *file) {
- char *str = NULL;
- int size = 32;
- int n = 0;
- while (true) {
- str = (char*)myrealloc(str, size);
- if (fgets(str + n, size - n, file) == NULL) {
- if (n != 0 && feof(file)) return str;
- free(str);
- return NULL;
- }
- if (hasEndl(str + n)) return str;
- n = size - 1;
- size *= 2;
- }
- }
- char* readLineS (FILE *file) {
- char *s = readLine(file);
- if (s == NULL) return NULL;
- char *r = stripSpaces(s);
- free(s);
- if (*r == '\0') {
- free(r);
- return NULL;
- }
- return r;
- }
- bool readIntLine (int *result) {
- char *s = readLine(stdin);
- if (s == NULL) return false;
- int n = 0;
- bool flag = true;
- if (sscanf(s, "%d %n", result, &n) != 1 || s[n] != '\0') flag = false;
- free(s);
- return flag;
- }
- bool readDoubleLine (double *result) {
- char *s = readLine(stdin);
- if (s == NULL) return false;
- int n = 0;
- bool flag = true;
- if (sscanf(s, "%ld %n", result, &n) != 1 || s[n] != '\0') flag = false;
- free(s);
- return flag;
- }
- Contestant* inputContestant () {
- Contestant *result = (Contestant*)mymalloc(sizeof(*result));
- result->firstName = NULL;
- result->lastName = NULL;
- result->interests = NULL;
- printf("Введите данные участнике\n");
- printf("Имя: ");
- result->firstName = readLineS(stdin);
- if (result->firstName == NULL) goto fail;
- printf("Фамилия: ");
- result->lastName = readLineS(stdin);
- if (result->lastName == NULL) goto fail;
- printf("Интересы: ");
- result->interests = readLineS(stdin);
- if (result->interests == NULL) goto fail;
- printf("Возраст: ");
- if (!readIntLine(&result->age)|| result->age < 0) goto fail;
- printf("Рост: ");
- if (!readIntLine(&result->height) || result->height < 0) goto fail;
- printf("Бюст: ");
- if (!readIntLine(&result->bwh.bust) || result->bwh.bust < 0) goto fail;
- printf("Талия: ");
- if (!readIntLine(&result->bwh.waist) || result->bwh.waist < 0) goto fail;
- printf("Бедро: ");
- if (!readIntLine(&result->bwh.hip) || result->bwh.hip < 0) goto fail;
- return result;
- fail:
- fprintf(stderr, "Ошибка ввода\n");
- destroyContestant(result);
- return NULL;
- }
- void stripContestant (Contestant *con) {
- char *lastName = con->lastName;
- char *firstName = con->firstName;
- char *interests = con->interests;
- con->firstName = stripSpaces(firstName);
- con->lastName = stripSpaces(lastName);
- con->interests = stripSpaces(interests);
- free(lastName);
- free(firstName);
- free(interests);
- }
- Contestant* readContestantLine (const char *str) {
- int len = strlen(str);
- Contestant *con = (Contestant*)mymalloc(sizeof(*con));
- con->firstName = (char*)mymalloc((len + 1) * sizeof(*con->firstName));
- con->lastName = (char*)mymalloc((len + 1) * sizeof(*con->lastName));
- con->interests = (char*)mymalloc((len + 1) * sizeof(*con->interests));
- int n;
- int res = sscanf(str, " %[^#] # %[^#] # %[^#] # %d # %d # %d # %d # %d %n",
- con->firstName, con->lastName, con->interests,
- &con->age, &con->height, &con->bwh.bust,&con->bwh.waist,&con->bwh.hip, &n);
- if (res != 8 || str[n] != '\0') goto fail;
- stripContestant(con);
- return con;
- fail:
- destroyContestant(con);
- return NULL;
- }
- bool isEmptyString (const char *str) {
- while (isspace(*str) && *str != '\0') str++;
- return *str == '\0';
- }
- void readFile (const char *path, Stack *stack) {
- emptyStack(stack);
- FILE *file = fopen(path, "r");
- if (file == NULL) {
- fprintf(stderr, "%s: %s\n", path, strerror(errno));
- printf("Ошибка чтения\n");
- return;
- }
- int line = 0;
- Contestant *con = NULL;
- char *str = NULL;
- for (;;) {
- line++;
- free(str);
- str = readLine(file);
- if (str == NULL) break;
- if (isEmptyString(str)) continue;
- con = readContestantLine(str);
- if (con == NULL) break;
- insertContestant(stack, con);
- }
- free(str);
- if (ferror(file)) {
- fprintf(stderr, "%s:%d: %s\n", path, line, strerror(errno));
- emptyStack(stack);
- printf("Ошибка чтения\n");
- clearerr(file);
- } else if (str != NULL && con == NULL) {
- fprintf(stderr, "%s:%d: Неправильный формат записи\n", path, line);
- emptyStack(stack);
- printf("Ошибка чтения\n");
- } else {
- printf("Файл успешно прочитан, всего %d записей с книгами\n", stack->n);
- }
- if (fclose(file) != 0) {
- fprintf(stderr, "%s: %s\n", path, strerror(errno));
- }
- }
- void doReadFile (Stack *stack) {
- printf("Чтения базы данных блюд из файла\n");
- printf("Введите название файла: ");
- char *s = readLineS(stdin);
- if (s == NULL) {
- printf("Ошибка ввода\n");
- return;
- }
- readFile(s, stack);
- free(s);
- }
- void writeContestantLine (FILE *file, Contestant *con) {
- fprintf(file, "%s # %s # %s # %d # %d # %d # %d # %d\n",
- con->firstName, con->lastName, con->interests,
- con->age, con->height, con->bwh.bust,con->bwh.waist,con->bwh.hip);
- }
- void writeFile (const char *path, Stack *stack) {
- FILE *file = fopen(path, "w");
- if (file == NULL) {
- fprintf(stderr, "%s: %s\n", path, strerror(errno));
- return;
- }
- Pair *p = stack->data;
- int i,n = stack->n;
- for (i = 0; i < n; i++) {
- writeContestantLine(file, p[i].con);
- if (ferror(file)) {
- fprintf(stderr, "%s:%d: %s\n", path, i, strerror(errno));
- clearerr(file);
- break;
- }
- }
- if (fclose(file) != 0) {
- fprintf(stderr, "%s: %s\n", path, strerror(errno));
- }
- }
- void doPrintContestant (Stack *stack) {
- printContestantArray(stack->data, stack->n);
- }
- void doRemoveContestant (Stack *stack) {
- int id;
- printf("Введите ID участника, которого нужно удалить: ");
- if (!readIntLine(&id)) {
- printf("Ошибка ввода\n");
- return;
- }
- if (!removeContestantId(stack, id)) {
- printf("Участника с таким ID нет в списке\n");
- }
- }
- void doWriteFile (Stack *stack) {
- printf("Запись базы данных участников в файл\n");
- printf("Введите название файла: ");
- char *s = readLineS(stdin);
- if (s == NULL) {
- printf("Ошибка ввода\n");
- return;
- }
- writeFile(s, stack);
- free(s);
- }
- typedef int (*Compare) (const void *a, const void *b);
- Pair* mySort (Pair *p, int n, int (*f) (Pair *a, Pair *b)) {
- Pair *r = (Pair*)mymalloc(n * sizeof(*r));
- memcpy(r, p, n * sizeof(*r));
- qsort(r, n, sizeof(*r), (Compare) f);
- return r;
- }
- int compareName (Pair *a, Pair *b) {
- //int result = strcmp(a->con->firstName, b->con->firstName) + strcmp(a->con->lastName,b->con->lastName);
- int result = strcmp(a->con->lastName, b->con->lastName);
- if (result != 0) return result;
- result = strcmp(a->con->firstName, b->con->firstName);
- return result;
- }
- void doSortName (Stack *stack) {
- Pair *xs = mySort(stack->data, stack->n, compareName);
- printf("Список участников отсортированный по названию: \n\n");
- printContestantArray(xs, stack->n);
- free(xs);
- }
- void doInputContestant (Stack *stack) {
- Contestant *con = inputContestant();
- insertContestant(stack, con);
- }
- void selectBWH(Pair* p,int n,int bustmin,int bustmax,int waistmin,int waistmax,int hipmin,int hipmax)
- {
- for(int i=0;i<n;i++) {
- if((p+i)->con->bwh.bust > bustmin && (p+i)->con->bwh.bust < bustmax && (p+i)->con->bwh.waist > waistmin && (p+i)->con->bwh.waist < waistmax && (p+i)->con->bwh.hip > hipmin && (p+i)->con->bwh.hip < hipmax ) {
- printPair(p+i);
- }
- }
- }
- void doBWHContestant (Stack *stack) {
- int bustmin,bustmax,waistmin,waistmax,hipmin,hipmax,i;
- printf("Bust min:");
- if(!readIntLine(&bustmin))
- {
- perror("Ошибка чтения!");
- exit(1);
- }
- printf("Bust max:");
- if(!readIntLine(&bustmax))
- {
- perror("Ошибка чтения!");
- exit(1);
- }
- printf("Waist min:");
- if(!readIntLine(&waistmin))
- {
- perror("Ошибка чтения!");
- exit(1);
- }
- printf("Waist max:");
- if(!readIntLine(&waistmax))
- {
- perror("Ошибка чтения!");
- exit(1);
- }
- printf("Hip min:");
- if(!readIntLine(&hipmin))
- {
- perror("Ошибка чтения!");
- exit(1);
- }
- printf("Hip max:");
- if(!readIntLine(&hipmax))
- {
- perror("Ошибка чтения!");
- exit(1);
- }
- Pair* p = stack->data;
- int n= stack->n;
- selectBWH(p,n,bustmin,bustmax,waistmin,waistmax,hipmin,hipmax);
- }
- void selectHeighContestant(Pair* p,int n, int height)
- {
- for(int i=0;i<n;i++) {
- if((p+i)->con->height > height ) {
- printPair(p+i);
- }
- }
- }
- void doHeightContestant(Stack* stack)
- {
- printf("Рост: ");
- int height;
- if (!readIntLine(&height)) {
- fprintf(stderr, "Ошибка ввода\n");
- return;
- }
- printf("\n");
- Pair* p = stack->data;
- int n= stack->n;
- selectHeighContestant(p,n,height);
- printf("\n");
- }
- Pair* filterInterests (const Pair *xs, int n, const char *str, int *m) {
- int k = 0, s = 32;
- Pair *p = (Pair*)mymalloc(s * sizeof(*p));
- for (int i = 0; i < n; i++) {
- if (strstr(xs[i].con->interests, str) != NULL) {
- if (k == s) {
- s *= 2;
- p = (Pair*)myrealloc(p, s * sizeof(*p));
- }
- p[k] = xs[i];
- k++;
- }
- }
- *m = k;
- return p;
- }
- void doFilterInterests (Stack *stack) {
- printf("Выбрать участников по интересам\n");
- printf("Введите один из интересов: ");
- char *s = NULL;
- Pair *xs = NULL;
- int n;
- s = readLineS(stdin);
- if (s == NULL) {
- printf("Ошибка чтения\n");
- return;
- }
- xs = filterInterests(stack->data, stack->n, s, &n);
- printf("Результаты (всего %d):\n\n", n);
- printContestantArray(xs, n);
- free(s);
- free(xs);
- }
- void doNothing (Stack *stack) {
- }
- typedef void (*Command) (Stack *stack);
- typedef struct CommandPair {
- int code;
- char *description;
- Command func;
- } CommandPair;
- CommandPair commands[] = {
- {'r', "прочитать список участников из файла", doReadFile},
- {'w', "записать список участников в файл", doWriteFile},
- {'i', "добавить нового участника", doInputContestant},
- {'d', "удалить из списка участника по его ID", doRemoveContestant},
- {'p', "вывести список участников", doPrintContestant},
- {'s', "сортировка по фамилии, имени", doSortName},
- {'t', "поиск по интересам", doFilterInterests},
- {'y', "вывод информации об участниках с ростом выше заданного", doHeightContestant},
- {'f', "вывод информации об участниках с заданными пропорциями тела, указывается нижним и верхним пределами", doBWHContestant},
- {'h', "вывести это сообщение", doNothing},
- {'q', "выйти из программы", doNothing},
- };
- int prompt () {
- int code = EOF;
- printf("Введите команду (h для справки): ");
- char *s = readLineS(stdin);
- if (s == NULL) return EOF;
- if (strlen(s) == 1) code = s[0];
- free(s);
- return code;
- }
- void printHelp () {
- int i,len = sizeof(commands) / sizeof(commands[0]);
- for (i = 0; i < len; i++) {
- printf("%c: %s\n", commands[i].code, commands[i].description);
- }
- }
- void dispatchCommand (Stack *stack, int code) {
- int i,len = sizeof(commands) / sizeof(commands[0]);
- for (i = 0; i < len; i++) {
- if (code == commands[i].code) {
- commands[i].func(stack);
- return;
- }
- }
- printf("Неизвестная команда\n");
- }
- int main () {
- Stack *stack = newStack();
- bool flag = true;
- char code;
- do {
- code = prompt();
- switch (code) {
- case 'h':
- printHelp();
- break;
- case 'q':
- flag = false;
- break;
- case EOF:
- if (feof(stdin)) flag = false;
- break;
- default:
- dispatchCommand(stack, code);
- break;
- }
- } while (flag);
- destroyStack(stack);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement