#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <locale.h> #define FIRST_NAME_SIZE 20 #define LAST_NAME_SIZE 30 #define GROUP_NAME_SIZE 30 #define MIN_YEAR 1900 #define MAX_YEAR 2010 #define N 20 #define ACTIVITIES_N 4 struct Child { char first_name[FIRST_NAME_SIZE]; char last_name[LAST_NAME_SIZE]; unsigned short int year; char group_name[GROUP_NAME_SIZE]; unsigned short int activities[4]; }; unsigned short int n = 0; struct Child *children; size_t size = sizeof(struct Child); char activities[][10] = {"nic", "rytmika", "angielski", "korektywa"}; /* 10 = długość najdłuższej nazwy+1 */ int main(void); int child_add(char *first_name, char *last_name, unsigned short int year, char *group_name, unsigned short int *activities); int child_del(unsigned short int i); void children_sort_by_group(void); void children_sort_alfanum(void); void children_show(void); void children_show_activity(unsigned short int t); void children_wipe(void); int check_first_name(char *first_name); int check_last_name(char *last_name); int check_group_name(char *group_name); int check_name(char *name); void intro(void); unsigned short int menu(void); int main(void) { unsigned short int choice, z, i, temp_year, temp_activities[ACTIVITIES_N]; short int e; char temp_first_name[FIRST_NAME_SIZE], temp_last_name[LAST_NAME_SIZE], temp_group_name[GROUP_NAME_SIZE]; choice = z = i = e = 0; setlocale(LC_ALL, ""); intro(); while (1) { choice = menu(); if (choice == 1) { children_sort_by_group(); children_show(); } else if (choice == 2) { children_sort_alfanum(); while (1) { printf("Wyświetl dzieci, które uczęszczają na:\n"); for (i = 0; i < ACTIVITIES_N; i++) { printf("%hu) %s\n", i, activities[i]); } printf("\n(0 - %hu) > ", ACTIVITIES_N - 1); z = scanf("%hu", &choice); if (z == 1 && choice > 0 && choice < ACTIVITIES_N) { break; } else { clearerr(stdin); scanf("%*[^\n]"); } } children_show_activity(choice); } else if (choice == 3 && n < N) { printf("Dodajemy\n"); while (1) { printf("Nazwisko > "); z = scanf("%s", temp_last_name); if (z == 1 && (e = check_last_name(temp_last_name))) { z = 0; break; } else { if (e == 0) { printf("Możesz użyć tylko znaków; "); } else if (e == -1) { printf("Najwyżej %d znaków; ", LAST_NAME_SIZE - 1); } clearerr(stdin); } } while (1) { printf("Imie > "); z = scanf("%s", temp_first_name); if (z == 1 && check_first_name(temp_first_name)) { z = 0; break; } else { clearerr(stdin); } } while (1) { printf("Rok urodzenia > "); z = scanf("%hu", &temp_year); if (z == 1 && temp_year > MIN_YEAR && temp_year < MAX_YEAR) { z = 0; break; } else { clearerr(stdin); scanf("%*[^\n]"); } } while (1) { printf("Grupa > "); z = scanf("%s", temp_group_name); if (z == 1 && check_group_name(temp_group_name)) { z = 0; break; } else { clearerr(stdin); } } for (i = 1; i < ACTIVITIES_N; i++) { while (1) { printf("%s (0 - nie, 1 - tak) > ", activities[i]); z = scanf("%hu", &choice); if (z == 1) { z = 0; temp_activities[i] = (choice > 0); break; } else { clearerr(stdin); scanf("%*[^\n]"); } } } child_add(temp_last_name, temp_first_name, temp_year, temp_group_name, temp_activities); } else if (n > 0 && choice == 4) { children_sort_by_group(); children_show(); if (n > 1) { while (1) { printf("Wpisz nr dziecka, które chcesz usunąć z listy (1 - %hd) > ", n); z = scanf("%hu", &choice); if (z == 1 && choice > 0 && choice < n) { break; } else { clearerr(stdin); scanf("%*[^\n]"); } } } child_del(choice - 1); } else if (choice == 0) { break; } printf("\n"); } children_wipe(); return EXIT_SUCCESS; } int child_add(char *last_name, char *first_name, unsigned short int year, char *group_name, unsigned short int *activities) { unsigned short int i, z; if (n == 0) { children = malloc(size); } else if (n < N) { children = realloc(children, (n + 1) * size); } else { return 0; } if (!children) { return 0; } n++; strncpy(children[n-1].first_name, first_name, FIRST_NAME_SIZE-1); strncpy(children[n-1].last_name, last_name, LAST_NAME_SIZE-1); children[n-1].year = year; strncpy(children[n-1].group_name, group_name, GROUP_NAME_SIZE-1); z = 0; for (i = 1; i < ACTIVITIES_N; i++) { if (activities[i] > 0) { children[n-1].activities[i] = 1; z++; } else { children[n-1].activities[i] = 0; } } children[n-1].activities[0] = (z == 0); return 1; } int child_del(unsigned short int i) { unsigned short int j, k; for (j = 0, k = 0; j < n; j++, k++) { if (k == i) { k++; n--; } children[j] = children[k]; } children = realloc(children, n * size); return 1; } void children_sort_by_group(void) { unsigned short int i, j; struct Child temp; for (i = 0; i < n-1; i++) { for (j = n-1; j > i; j--) { if ( (strcmp(children[j-1].group_name, children[j].group_name) > 0) || (strcmp(children[j-1].group_name, children[j].group_name) == 0 && strcmp(children[j-1].last_name, children[j].last_name) > 0) || (strcmp(children[j-1].group_name, children[j].group_name) == 0 && strcmp(children[j-1].last_name, children[j].last_name) == 0 && strcmp(children[j-1].first_name, children[j].first_name) > 0) ) { temp = children[j]; children[j] = children[j-1]; children[j-1] = temp; } } } } void children_sort_alfanum(void) { unsigned short int i, j; struct Child temp; for (i = 0; i < n-1; i++) { for (j = n-1; j > i; j--) { if ( (strcmp(children[j-1].last_name, children[j].last_name) > 0) || (strcmp(children[j-1].last_name, children[j].last_name) == 0 && strcmp(children[j-1].first_name, children[j].first_name) > 0) ) { temp = children[j]; children[j] = children[j-1]; children[j-1] = temp; } } } } void children_show(void) { unsigned short int i, j, q; printf("-\t-\t-\t-\t-\t-\n"); if (n == 0) { printf("Lista jest pusta\n"); } else { printf("L.p.\tGrupa\tNazwisko\tImię\tRok urodzenia\tZajęcia dodatkowe\n"); for (i = 0; i < n; i++) { printf("%hu\t%s\t%s\t%s\t%hu", i+1, children[i].group_name, children[i].last_name, children[i].first_name, children[i].year); q = 0; for (j = 1; j < ACTIVITIES_N; j++) { if (children[i].activities[j]) { if (q != 0) { printf(", "); } else { printf("\t"); } printf("%s", activities[j]); q++; } } printf("\n"); } } printf("-\t-\t-\t-\t-\t-\n"); } void children_show_activity(unsigned short int t) { unsigned short int i, q; q = 0; printf("-\t-\t-\t-\t-\t-\n"); if (n == 0) { printf("Lista jest pusta\n"); } else { printf("Lista dzieci uczęszczających na: %s\n", activities[t]); printf("L.p.\tNazwisko\tImię\tRok urodzeina\tGrupa\n"); for (i = 0; i < n; i++) { if (children[i].activities[t]) { printf("%hu\t%s\t%s\t%hu\t%s\n", i+1, children[i].last_name, children[i].first_name, children[i].year, children[i].group_name); q++; } } if (q == 0) { printf("brak\n"); } } printf("-\t-\t-\t-\t-\t-\n"); } void children_wipe(void) { if (n > 0) { free(children); n = 0; } } int check_first_name(char *first_name) { if (strlen(first_name) > FIRST_NAME_SIZE - 1) { return -1; } return check_name(first_name); } int check_last_name(char *last_name) { if (strlen(last_name) > LAST_NAME_SIZE - 1) { return -1; } return check_name(last_name); } int check_group_name(char *group_name) { return (strlen(group_name) <= GROUP_NAME_SIZE - 1) ? 1 : -1; } int check_name(char *name) { unsigned short int i, len; len = strlen(name); for (i = 0; i < len; i++) { if (!isalpha((unsigned char)name[i])) { return 0; } } return 1; } void intro(void) { printf("Intro\n"); } unsigned short int menu(void) { unsigned short int z, choice; /* TODO Wyróżnić wszystkie sytuacje z możliwymi akcjami, potem przetentegować na konkretne id akcji */ printf("Wybierz jedną z opcji:\n1) Wyświetl wg grup\n2) Wyświetl wg zajęcia dodatkowego\n"); if (n < N) { printf("3) Dodaj\n"); } if (n > 0) { printf("4) Usuń\n"); } printf("0) Zakończ\n"); while (1) { if (n > 0 && n < N) { printf("(0 - 4) > "); } else if (n < N) { printf("(0 - 3) > "); } else if (n > 0) { printf("(0, 1, 2, 4) > "); } z = scanf("%hu", &choice); if (z == 1 && ((n > 0 && choice < 5) || (n == 0 && choice < 4))) { break; } else { clearerr(stdin); scanf("%*[^\n]"); } } printf("\n"); return choice; }