VEndymionV

Untitled

Jun 13th, 2017
168
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 15.62 KB | None | 0 0
  1. #include "stdio.h"
  2. #include "stdlib.h"
  3. #include "string.h"
  4.  
  5. typedef struct Dane_osoby Osoby;
  6. typedef struct Lista_osob Lista;
  7. Lista *stworz_element();
  8. void dodaj_na_poczatek(Lista**);
  9. void dodaj_na_koniec(Lista**);
  10. void wyswietlanie_listy(Lista*);
  11. void wybor(Lista*);
  12. char *string();
  13. void odczyt_z_pliku(Lista **start);
  14. void usun_liste(Lista **start);
  15. void usun_nazwisko(Lista **start);
  16. void sortowanie_po_nazwisku(Lista **start);
  17.  
  18. struct Dane_osoby
  19. {
  20.     char *imie, *nazwisko, *PESEL;
  21.     int wiek;
  22. };
  23.  
  24. struct Lista_osob
  25. {
  26.     Osoby dane;
  27.     Lista *poprzedni, *nastepny;
  28. };
  29.  
  30. Lista *stworz_element()
  31. {
  32.  
  33.     Lista *element = (Lista*)malloc(sizeof(Lista)); // Alokacja pamięci na pojedyńczy element.
  34.  
  35.     element->poprzedni = NULL, element->nastepny = NULL;
  36.  
  37.     printf("Podaj imie: ");
  38.     element->dane.imie = string();
  39.  
  40.     printf("Podaj nazwisko: ");
  41.     element->dane.nazwisko = string();
  42.  
  43.     printf("Podaj numer PESEL: ");
  44.     element->dane.PESEL = string();
  45.  
  46.     printf("Podaj wiek: ");
  47.     scanf("%d", &(element->dane.wiek));
  48.  
  49.     getchar();
  50.  
  51.     return element;
  52. }
  53.  
  54. void dodaj_na_poczatek(Lista **start)
  55. {
  56.     Lista *tymczasowa = stworz_element(); // "tymczasowa" przechowuje stworzony element tzn. imie, nazwisko, PESEL, wiek oraz wskaźnik na element poprzedni i następny (NULL).
  57.  
  58.     if (*start != NULL) // Jeżeli istniejąca już lista nie jest pusta.
  59.     {
  60.         (*start)->poprzedni = tymczasowa; // Pierwszy element istniejącej listy wskazuje na element stworzony.
  61.         tymczasowa->nastepny = *start; // Stworzony element wskazuje na początek istniejącej już listy.
  62.     }
  63.  
  64.     *start = tymczasowa; // Listą "główną" staje się lista która posiada nowo stworzony element który znajduje się na początku listy (poprzedni = NULL, następny = istniejąca już lista/NULL).
  65. }
  66.  
  67. void dodaj_na_koniec(Lista **start)
  68. {
  69.     Lista *tymczasowa, *pomocnicza;
  70.     tymczasowa = stworz_element(); // "tymczasowa" przechowuje nowo stworzony element listy.
  71.  
  72.     if (*start != NULL) // Jeżeli istniejąca lista nie jest pusta.
  73.     {
  74.         pomocnicza = *start;
  75.         while (pomocnicza->nastepny != NULL) pomocnicza = pomocnicza->nastepny; // Dopóki wskaźnik na następny element pomocniczej (która wskazuje na istniejącą już liste) nie jest pusty.
  76.         tymczasowa->poprzedni = pomocnicza; // Nowo stworzony element wskazuje na istniejącą już listę (poprzedni).
  77.         pomocnicza->nastepny = tymczasowa; // Istniejąca już lista wskazuje na nowo stworzony element.
  78.         return; // "Wychodzi" z funkcji. Istniejącą lista zostaje w swojej pierwotnej kolejności, jej ostatni element wskazuje na nowo stworzony element.
  79.     }
  80.  
  81.     *start = tymczasowa; // Jeżeli istniejąca lista była pusta (nie było jej...), listą główną staje się stworzony element.
  82. }
  83.  
  84. void wyswietlanie_listy(Lista *start)
  85. {
  86.     Lista *tymczasowa = start;
  87.  
  88.     while (tymczasowa != NULL) // Dopóki tymczasowa (która wskazuje na liste już istniejącą) nie jest pusta.
  89.     {
  90.         printf("Imie: %s\n", tymczasowa->dane.imie);
  91.         printf("Naziwsko: %s\n", tymczasowa->dane.nazwisko);
  92.         printf("Wiek: %d\n", tymczasowa->dane.wiek);
  93.         printf("Numer PESEL: %s\n", tymczasowa->dane.PESEL);
  94.         printf("______________________________________________________________________________\n"); // Oddzielenie kolejnych osób.
  95.         tymczasowa = tymczasowa->nastepny; // Przesunięcię na kolejną osobe, jezeli nie ma (czyli tymczasowa->następny wskazuje na NULL) wychodzi z pętli.
  96.     }
  97. }
  98.  
  99. void wyswietlanie_elementu(Lista *element) // Wyświetla pojedyńczy element (używana przy wyszukiwaniu osób o podanym nazwisku).
  100. {
  101.     if (element != NULL)
  102.     {
  103.         printf("Imie: %s\n", element->dane.imie);
  104.         printf("Naziwsko: %s\n", element->dane.nazwisko);
  105.         printf("Wiek: %d\n", element->dane.wiek);
  106.         printf("Numer PESEL: %s\n", element->dane.PESEL);
  107.         printf("______________________________________________________________________________\n"); // Oddziela kolejne osoby.
  108.     }
  109. }
  110.  
  111. Lista *wyszukiwanie_po_nazwisku(Lista *start, char *nazwisko)
  112. {
  113.     Lista *pomocnicza = start;
  114.     while (pomocnicza != NULL && (strcmp(nazwisko, pomocnicza->dane.nazwisko) != 0)) pomocnicza = pomocnicza->nastepny;
  115.     /*
  116.     ^ Dopóki pomocnicza (wskazująca na istniejącą liste) nie jest pusta i funkcja porównująca nazwisko które ma być wyszukane z nazwiskiem z listy jest różne od 0
  117.     to pomocnicza zostaje przesunięta na kolejną osobę.
  118.     strcmp(napis1, napis2) zwraca 0 gdy napis1 jest taki sam jak napis2.
  119.     */
  120.     return pomocnicza;
  121. }
  122.  
  123. void wyszukiwanie_wszystkich_o_nazwisku(Lista *start)
  124. {
  125.     Lista *nazwiska = start;
  126.     char *nazwisko;
  127.     printf("Podaj jakie nazwisko chcesz wyszukac: ");
  128.     nazwisko = string();
  129.     system("cls");
  130.     while (nazwiska != NULL) // Dopóki lista "nazwiska" (która wskazuje na początku na listę główną) nie jest pusta.
  131.     {
  132.         nazwiska = wyszukiwanie_po_nazwisku(nazwiska, nazwisko); // Wyszukuje pojedyńczy element który przechowuje szukane nazwisko.
  133.         wyswietlanie_elementu(nazwiska); // Wyświetla pojedyńczy element.
  134.         if (nazwiska != NULL) nazwiska = nazwiska->nastepny; // Jeżeli lista "nazwiska" nie jest pusta pętla się powtarza, wyszukuje nazwisko zaczynając od elementu który już wyświetliło.
  135.     }
  136.     nazwisko = NULL;
  137.     free(nazwisko);
  138. }
  139.  
  140. char* string()
  141. {
  142.     char *napis, znak;
  143.     znak = '\n';
  144.     int i, j;
  145.     i = 0;
  146.     j = 1;
  147.     napis = (char*)malloc(sizeof(char)); // Alokuje pamięć na pojedyńczy znak.
  148.     do
  149.     {
  150.         znak = getchar(); // Pobiera pojedyńczy znak.
  151.         napis = (char*)realloc(napis, j * sizeof(char)); // Zmienia rozmiar alokowanej pamięci dla napisu na j-znaków.
  152.         napis[i] = znak; // Kolejne elementy tablicy znaków przyjmują kolejne zczytane z klawiatury znaki.
  153.         i++; j++;
  154.     } while (znak != '\n'); // Jeżeli zczytamy znak nowej lini (użytkownik wciśnie ENTER) kończymy pętle.
  155.     napis[i-1] = '\0'; // Dodajemy znak kończący na koniec tablicy ([i-1] ponieważ przy ostatnim przejściu pętli i zostało zwiększone o 1).
  156.     return napis; // Zwraca tablice znaków "napis".
  157. }
  158.  
  159. void zapis_do_pliku(Lista *start)
  160. {
  161.     printf("Podaj nazwe pliku: ");
  162.     char *nazwa_pliku = string();
  163.     FILE *zapis = fopen(nazwa_pliku, "w"); // Tworzy lub otwiera plik o podanej wcześniej nazwie do zapisu.
  164.  
  165.     if (zapis == NULL) // Jeżeli nie udało się otworzyć/stworzyć pliku.
  166.     {
  167.         printf("Blad przy tworzeniu/otwieraniu pliku!\n");
  168.         return;
  169.     }
  170.  
  171.     Lista *tymczasowa = start;
  172.  
  173.     while (tymczasowa != NULL) // Dopóki tymczasowa (wskazująca na listę główną) nie jest pusta.
  174.     {
  175.         fprintf(zapis, "%s", tymczasowa->dane.imie);
  176.         fprintf(zapis, " %s", tymczasowa->dane.nazwisko);
  177.         fprintf(zapis, " %d", tymczasowa->dane.wiek);
  178.         fprintf(zapis, " %s\n", tymczasowa->dane.PESEL);
  179.         // ^ Zapisuje kolejne dane do pliku.
  180.         tymczasowa = tymczasowa->nastepny; // Przesunięcie tymczasowej na następny element.
  181.     }
  182.     fclose(zapis); // Zamyka plik.
  183.     nazwa_pliku = NULL;
  184.     free(nazwa_pliku); // Czyści pamięć po dynamicznie alokowanej nazwie pliku.
  185.     printf("Lista zapisana do pliku!\n");
  186. }
  187.  
  188. void odczyt_z_pliku(Lista **start)
  189. {
  190.     Lista *pomocnicza;
  191.     char bufor[100]; // Bufor pomocniczy.
  192.     printf("Podaj nazwe pliku: ");
  193.     char *nazwa_pliku = string();
  194.     FILE *odczyt = fopen(nazwa_pliku, "r"); // Otwiera plik o podanej wcześniej nazwie do odczytu.
  195.     if (odczyt == NULL) // Jeżeli nie udało się otworzyć pliku.
  196.     {
  197.         printf("Blad przy tworzeniu/otwieraniu pliku!");
  198.         return;
  199.     }
  200.  
  201.     while (fscanf(odczyt, "%s", bufor) != EOF) // Dopóki nie osiągnie końca pliku.
  202.     {
  203.         Lista *element = (Lista*)malloc(sizeof(Lista)); // Alokuje pamięć na pojedyńczy element.
  204.  
  205.         element->poprzedni, element->nastepny = NULL;
  206.  
  207.         element->dane.imie = (char*)malloc(sizeof(char) * strlen(bufor));
  208.         strcpy(element->dane.imie, bufor);
  209.  
  210.         fscanf(odczyt, "%s", bufor);
  211.         element->dane.nazwisko = (char*)malloc(sizeof(char) * strlen(bufor));
  212.         strcpy(element->dane.nazwisko, bufor);
  213.  
  214.         fscanf(odczyt, "%d", &(element->dane.wiek));
  215.  
  216.         fscanf(odczyt, "%s", bufor);
  217.         element->dane.PESEL = (char*)malloc(sizeof(char) * strlen(bufor));
  218.         strcpy(element->dane.PESEL, bufor);
  219.         // strlen(napis) funkcja zwraca rozmiar tablicy znaków.
  220.         // strcpy(napis1, napis2) funkcja kopiuje znak po znaku aż do znaku kończącego '\0'.
  221.  
  222.         if (*start != NULL) // Jeżeli lista główna nie jest pusta.
  223.         {
  224.             pomocnicza = *start;
  225.             while (pomocnicza->nastepny != NULL) pomocnicza = pomocnicza->nastepny; // Przesuwa liste pomocniczą (wskazującą na listę główną) aż osiagnie jej koniec.
  226.             element->poprzedni = pomocnicza; // Nowo stworzony element (z danymi z pliku) znajduje się na końcu listy głównej i wskazuje na nią.
  227.             pomocnicza->nastepny = element; // Lista główna wskazuje na nowo stworzony element.
  228.         }
  229.  
  230.         else
  231.         {
  232.             *start = element; // Jeżeli lista główna była pusta.
  233.             (*start)->poprzedni = NULL, (*start)->nastepny = NULL;
  234.         }
  235.     }
  236.     fclose(odczyt); // Zamyka plik.
  237.  
  238.     nazwa_pliku = NULL;
  239.     free(nazwa_pliku); // Czyści pamięć po dynamicznie alokowanej nazwie pliku.
  240.  
  241.     printf("Lista zostala wczytana z pliku.\n");
  242. }
  243.  
  244. void usun_liste(Lista **start)
  245. {
  246.     Lista *do_usuniecia;
  247.     while (*start != NULL) // Dopóki lista główna nie jest pusta.
  248.     {
  249.         do_usuniecia = *start;
  250.         *start = (*start)->nastepny; // Przesunięcie listy głównej na następny element.
  251.         if (do_usuniecia->dane.imie)
  252.         {
  253.             do_usuniecia->dane.imie = NULL;
  254.             free(do_usuniecia->dane.imie);
  255.         }
  256.  
  257.         if (do_usuniecia->dane.nazwisko)
  258.         {
  259.             do_usuniecia->dane.nazwisko = NULL;
  260.             free(do_usuniecia->dane.nazwisko);
  261.         }
  262.  
  263.         if (do_usuniecia->dane.PESEL)
  264.         {
  265.             do_usuniecia->dane.PESEL = NULL;
  266.             free(do_usuniecia->dane.PESEL);
  267.         }
  268.         // ^ Usuwa kolejne dane (czyści pamięć).
  269.         free(do_usuniecia); // Usuwa cały element (czyści pamięć).
  270.     }
  271. }
  272.  
  273. void usun_nazwisko(Lista **start)
  274. {
  275.     Lista *pomocnicza;
  276.     Lista *nazwiska;
  277.     char *nazwisko;
  278.     printf("Podaj osobe z jakim nazwiskiem chcesz usunac z listy: ");
  279.     nazwisko = string();
  280.     system("cls");
  281.     nazwiska = wyszukiwanie_po_nazwisku(*start, nazwisko); // "nazwiska" będzie przechowywać element listy z osobą o danym nazwisku.
  282.  
  283.     if (nazwiska == NULL) // Jeżeli nie ma szukanej osoby na liście.
  284.     {
  285.         printf("Brak osob o podanym nazwisku!\n");
  286.         system("pause");
  287.         system("cls");
  288.     }
  289.     else
  290.     {
  291.         if (nazwiska == *start) // Jeżeli na liście jest tylko jedna osoba (i posiada wyszukiwane nazwisko).
  292.         {
  293.             *start = (*start)->nastepny;
  294.             if (nazwiska->dane.imie)
  295.             {
  296.                 nazwiska->dane.imie = NULL;
  297.                 free(nazwiska->dane.imie);
  298.             }
  299.             if (nazwiska->dane.nazwisko)
  300.             {
  301.                 nazwiska->dane.nazwisko = NULL;
  302.                 free(nazwiska->dane.nazwisko);
  303.             }
  304.             if (nazwiska->dane.PESEL)
  305.             {
  306.                 nazwiska->dane.PESEL = NULL;
  307.                 free(nazwiska->dane.PESEL);
  308.             }
  309.             // ^ Usuwa dane szukanej osoby (czyści pamięć).
  310.             free(nazwiska); // Usuwa element z listy (czyści pamięć).
  311.         }
  312.         else
  313.         {
  314.             pomocnicza = *start;
  315.             while ((strcmp(pomocnicza->nastepny->dane.nazwisko, nazwiska->dane.nazwisko) != 0)) pomocnicza = pomocnicza->nastepny; // Dopóki nie znajdzie na liście pomocniczej nazwiska.
  316.             if (nazwiska->nastepny != NULL) pomocnicza->nastepny->poprzedni = nazwiska->poprzedni;
  317.             // ^ Jeżeli element z osobą o szukanym nazwisku nie był ostatni to następny element listy pomocniczej jako wskaźnik na element poprzedni przechowuje wskaźnik na poprzedni element
  318.             // listy która zaczyna się od elementu z wyszukanym nazwiskiem.
  319.  
  320.             pomocnicza->nastepny = nazwiska->nastepny;
  321.  
  322.             if (nazwiska->dane.imie)
  323.             {
  324.                 nazwiska->dane.imie = NULL;
  325.                 free(nazwiska->dane.imie);
  326.             }
  327.             if (nazwiska->dane.nazwisko)
  328.             {
  329.                 nazwiska->dane.nazwisko = NULL;
  330.                 free(nazwiska->dane.nazwisko);
  331.             }
  332.             if (nazwiska->dane.PESEL)
  333.             {
  334.                 nazwiska->dane.PESEL = NULL;
  335.                 free(nazwiska->dane.PESEL);
  336.             }
  337.             // ^ Usuwa dane szukanej osoby (czyści pamięć).
  338.             free(nazwiska); // Usuwa element z listy (czyści pamięć).
  339.         }
  340.        
  341.     }
  342.     printf("Osoba usunieta.\n");
  343.     system("pause");
  344.     system("cls");
  345. }
  346.  
  347. void sortowanie_po_nazwisku(Lista **start)
  348. {
  349.     Lista *tymczasowa, *pomocnicza;
  350.     Lista *nowa = NULL;
  351.  
  352.     while (*start != NULL)
  353.     {
  354.         tymczasowa = (Lista*)malloc(sizeof(Lista));
  355.  
  356.         tymczasowa->dane.imie = (char*)malloc(sizeof(char)* strlen((*start)->dane.imie) + 1);
  357.         strcpy(tymczasowa->dane.imie, (*start)->dane.imie);
  358.  
  359.         tymczasowa->dane.nazwisko = (char*)malloc(sizeof(char)* strlen((*start)->dane.nazwisko) + 1);
  360.         strcpy(tymczasowa->dane.nazwisko, (*start)->dane.nazwisko);
  361.  
  362.         tymczasowa->dane.PESEL = (char*)malloc(sizeof(char)* strlen((*start)->dane.PESEL) + 1);
  363.         strcpy(tymczasowa->dane.PESEL, (*start)->dane.PESEL);
  364.  
  365.         tymczasowa->dane.wiek = (*start)->dane.wiek;
  366.  
  367.         tymczasowa->nastepny = NULL;
  368.         tymczasowa->poprzedni = NULL;
  369.  
  370.         if (nowa == NULL)
  371.             nowa = tymczasowa;
  372.         else if (strcmp(nowa->dane.nazwisko, tymczasowa->dane.nazwisko) > 0)
  373.         {
  374.             tymczasowa->nastepny = nowa;
  375.             nowa->poprzedni = tymczasowa;
  376.             nowa = tymczasowa;
  377.         }
  378.         else
  379.         {
  380.             pomocnicza = nowa;
  381.             while (pomocnicza->nastepny != NULL && strcmp(pomocnicza->nastepny->dane.nazwisko, tymczasowa->dane.nazwisko) < 0)
  382.                 pomocnicza = pomocnicza->nastepny;
  383.             tymczasowa->poprzedni = pomocnicza;
  384.             tymczasowa->nastepny = pomocnicza->nastepny;
  385.             if (pomocnicza->nastepny != NULL)
  386.                 pomocnicza->nastepny->poprzedni = tymczasowa;
  387.             pomocnicza->nastepny = tymczasowa;
  388.         }
  389.         pomocnicza = *start;
  390.         *start = (*start)->nastepny;
  391.  
  392.         if (pomocnicza->dane.imie)
  393.         {
  394.             pomocnicza->dane.imie = NULL;
  395.             free(pomocnicza->dane.imie);
  396.         }
  397.         if (pomocnicza->dane.nazwisko)
  398.         {
  399.             pomocnicza->dane.nazwisko = NULL;
  400.             free(pomocnicza->dane.nazwisko);
  401.         }
  402.         if (pomocnicza->dane.PESEL)
  403.         {
  404.             pomocnicza->dane.PESEL = NULL;
  405.             free(pomocnicza->dane.PESEL);
  406.         }
  407.         free(pomocnicza);
  408.         // ^ Usuwanie i czyszczenie pamięci po liście pomocniczej.
  409.     }
  410.     *start = nowa;
  411. }
  412.  
  413. void wybor(Lista *start)
  414. {
  415.     char wb, tn;
  416.     do
  417.     {
  418.         printf("1. Dodaj nowy element na poczatek listy.\n");
  419.         printf("2. Dodaj nowy element na koniec listy.\n");
  420.         printf("3. Wyswietl liste.\n");
  421.         printf("4. Wyszukaj wszystkich o nazwisku.\n");
  422.         printf("5. Zapis do pliku tekstowego.\n");
  423.         printf("6. Pobierz dane z pliku tekstowego.\n");
  424.         printf("7. Usun osobe o danym nazwisku.\n");
  425.         printf("8. Posortuj liste alfabetycznie po nazwisku.\n");
  426.         printf("9. Wyczysc liste.\n");
  427.         printf("0. Wyjdz\n");
  428.         wb = getchar();
  429.         getchar();
  430.         switch (wb)
  431.         {
  432.         case '0':
  433.             printf("Koncze dzialanie programu...\n");
  434.             break;
  435.         case '1':
  436.             printf("Dodaje element na poczatek listy...\n");
  437.             dodaj_na_poczatek(&start);
  438.             system("cls");
  439.             break;
  440.         case '2':
  441.             printf("Dodaje element na koniec listy...\n");
  442.             dodaj_na_koniec(&start);
  443.             system("cls");
  444.             break;
  445.         case '3':
  446.             printf("Wyswietlam liste...\n");
  447.             wyswietlanie_listy(start);
  448.             getchar();
  449.             system("cls");
  450.             break;
  451.         case '4' :
  452.             wyszukiwanie_wszystkich_o_nazwisku(start);
  453.             getchar();
  454.             system("cls");
  455.             break;
  456.         case '5' :
  457.             zapis_do_pliku(start);
  458.             system("pause");
  459.             system("cls");
  460.             break;
  461.         case '6' :
  462.             printf("Czy wyczyscic liste przed dodadniem?[T/t]");
  463.             tn = getchar();
  464.             if (tn == 't' || tn == 'T') usun_liste(&start);
  465.             getchar();
  466.             odczyt_z_pliku(&start);
  467.             system("pause");
  468.             system("cls");
  469.             break;
  470.         case '7' :
  471.             usun_nazwisko(&start);
  472.             break;
  473.         case '8' :
  474.             sortowanie_po_nazwisku(&start);
  475.             printf("Lista zostala posortowana.\n");
  476.             system("pause");
  477.             system("cls");
  478.             break;
  479.         case '9' :
  480.             usun_liste(&start);
  481.             printf("Lista zostala wyczyszczona.\n");
  482.             system("pause");
  483.             system("cls");
  484.             break;
  485.         default:
  486.             printf("Zly wybor!\n");
  487.             getchar();
  488.             system("cls");
  489.             break;
  490.         }
  491.     } while (wb != '0');
  492. }
  493.  
  494. int main()
  495. {
  496.     Lista *start = NULL;
  497.     wybor(start);
  498.     usun_liste(&start);
  499.     system("pause");
  500.     return 0;
  501. }
Advertisement
Add Comment
Please, Sign In to add comment