#include #include #include #include #include struct kontakt_dane { char imie[30]; char nazwisko[30]; char numer[10]; char grupa[30]; }; //Strukturę – element listy, zawierający kontakt i adresy do struktur tego samego typu – elementu poprzedniego i następnego; struct element { struct element* poprzedni; struct element* nastepny; struct kontakt_dane kontakt; }; void wyczyscbufor() { int c; while (((c = getc(stdin)) != 'n') && (c != EOF)); } //Funkcje wczytującą kontakty z pliku .CSV i formującą listę. /* Dynamiczna struktura danych, gdzie każdy element listy przechowuje odniesienie (adres) zarówno do poprzedzającego jak i następnego elementu. Taka relacja pozwala na swobodne przemieszczanie się na liście w obu kierunkach void wczytywanie_z_pliku(struct element** poczatek,struct element** gora) */ void wczytywanie_z_pliku(struct element** poczatek, struct element** gora) { FILE* plik; char* nazwa_pliku; struct element* osoba; struct element* poprzedni; poprzedni = calloc(1, sizeof(struct element)); nazwa_pliku = calloc(20, sizeof(char)); while (1) { printf("Podaj nazwe pliku:n"); scanf("%s", nazwa_pliku); plik = fopen(nazwa_pliku, "r"); if (plik == NULL) { printf("Podano zla nazwe pliku. Sprobuj ponownie.n"); wyczyscbufor(); } else { break; } } while (feof(plik) == 0) { osoba = calloc(1, sizeof(struct element)); fscanf(plik, "%[^;] ; %[^;] ; %[^;] ; %sn", osoba->kontakt.imie, osoba->kontakt.nazwisko, osoba->kontakt.numer, osoba->kontakt.grupa); if (*poczatek != NULL) { osoba->poprzedni = poprzedni; osoba->poprzedni->nastepny = osoba; osoba->nastepny = NULL; poprzedni = osoba; *gora = osoba; } if (*poczatek == NULL) { osoba->poprzedni = NULL; osoba->nastepny = NULL; poprzedni = osoba; *poczatek = osoba; } } fclose(plik); } void wyswietlanie_kontatkow(struct element* poczatek) { struct element* aktualny; int i = 1; aktualny = calloc(1, sizeof(aktualny)); aktualny = poczatek; printf("Ksiazka telefoniczna:n"); while (aktualny != NULL) { printf("%d)%s %s %s %sn", i, aktualny->kontakt.imie, aktualny->kontakt.nazwisko, aktualny->kontakt.numer, aktualny->kontakt.grupa); aktualny = aktualny->nastepny; i++; } free(aktualny); } void sortowanie(struct element** poczatek,struct element** gora, int sort) { struct element* aktualny; int zmiana = 1; aktualny = calloc(1, sizeof(struct element)); aktualny = *poczatek; if(sort==1) { while (zmiana != 0) { zmiana = 0; while ((*aktualny).nastepny != NULL) { if (strcoll((*aktualny).kontakt.imie, (*aktualny).nastepny->kontakt.imie) == 1) //Jeden jeśli pierwszy ciąg znaków jest niżej według kolejności alfabetycznej niż drugi. { zmiana += 1; if ((*aktualny).poprzedni != NULL && (*aktualny).nastepny != NULL) { /* Między dwoma elementami oraz elementami sąsiadującymi z nimi występuje do sześciu „powiązań” adresów, stąd algorytm zamiany dwóch elementów składa się z sześciu „podmian” adresów. Należy zwrócić uwagę na możliwość wzięcia udziału w zamianie skrajnych elementów, (przy zamianach pierwszy z drugim lub ostatni z przedostatnim), które wskazują na NULL. */ (*aktualny).poprzedni->nastepny = (*aktualny).nastepny; (*aktualny).nastepny->poprzedni = (*aktualny).poprzedni; (*aktualny).poprzedni = (*aktualny).nastepny; (*aktualny).nastepny = (*aktualny).poprzedni->nastepny; (*aktualny).poprzedni->nastepny = aktualny; if ((*aktualny).nastepny != NULL) { (*aktualny).nastepny->poprzedni = aktualny; } else { (*aktualny).nastepny = NULL; *gora = aktualny; /* zastosowanie, aby program nie myslal, ze gora to ciagle ten sam element, ktory byl uzywany na poczatku */ } } if ((*aktualny).poprzedni == NULL) { (*aktualny).nastepny->poprzedni = (*aktualny).poprzedni; (*aktualny).poprzedni = (*aktualny).nastepny; if ((*aktualny).nastepny->nastepny != NULL) { (*aktualny).nastepny = (*aktualny).nastepny->nastepny; (*aktualny).nastepny->poprzedni = aktualny; } else { (*aktualny).nastepny = NULL; } (*aktualny).poprzedni->nastepny = aktualny; *poczatek = aktualny->poprzedni; } } else { aktualny = aktualny->nastepny; } } aktualny = *poczatek; } printf("Posortowano wedlug imion.n"); } if(sort == 2) { while (zmiana != 0) { zmiana = 0; while ((*aktualny).nastepny != NULL) { if (strcoll((*aktualny).kontakt.nazwisko, (*aktualny).nastepny->kontakt.nazwisko) == 1) { zmiana += 1; if ((*aktualny).poprzedni != NULL && (*aktualny).nastepny != NULL) { (*aktualny).poprzedni->nastepny = (*aktualny).nastepny; (*aktualny).nastepny->poprzedni = (*aktualny).poprzedni; (*aktualny).poprzedni = (*aktualny).nastepny; (*aktualny).nastepny = (*aktualny).poprzedni->nastepny; (*aktualny).poprzedni->nastepny = aktualny; if ((*aktualny).nastepny != NULL) { (*aktualny).nastepny->poprzedni = aktualny; } else { (*aktualny).nastepny = NULL; *gora = aktualny; } } if ((*aktualny).poprzedni == NULL) { (*aktualny).nastepny->poprzedni = (*aktualny).poprzedni; (*aktualny).poprzedni = (*aktualny).nastepny; if ((*aktualny).nastepny->nastepny != NULL) { (*aktualny).nastepny = (*aktualny).nastepny->nastepny; (*aktualny).nastepny->poprzedni = aktualny; } else { (*aktualny).nastepny = NULL; } (*aktualny).poprzedni->nastepny = aktualny; *poczatek = aktualny->poprzedni; } } else { aktualny = aktualny->nastepny; } } aktualny = *poczatek; } printf("Posortowano wedlug nazwisk.n"); } if(sort == 3) { while (zmiana != 0) { zmiana = 0; while ((*aktualny).nastepny != NULL) { if (strcoll((*aktualny).kontakt.grupa, (*aktualny).nastepny->kontakt.grupa) == 1) { zmiana += 1; if ((*aktualny).poprzedni != NULL && (*aktualny).nastepny != NULL) { (*aktualny).poprzedni->nastepny = (*aktualny).nastepny; (*aktualny).nastepny->poprzedni = (*aktualny).poprzedni; (*aktualny).poprzedni = (*aktualny).nastepny; (*aktualny).nastepny = (*aktualny).poprzedni->nastepny; (*aktualny).poprzedni->nastepny = aktualny; if ((*aktualny).nastepny != NULL) { (*aktualny).nastepny->poprzedni = aktualny; } else { (*aktualny).nastepny = NULL; *gora = aktualny; } } if ((*aktualny).poprzedni == NULL) { (*aktualny).nastepny->poprzedni = (*aktualny).poprzedni; (*aktualny).poprzedni = (*aktualny).nastepny; if ((*aktualny).nastepny->nastepny != NULL) { (*aktualny).nastepny = (*aktualny).nastepny->nastepny; (*aktualny).nastepny->poprzedni = aktualny; } else { (*aktualny).nastepny = NULL; } (*aktualny).poprzedni->nastepny = aktualny; *poczatek = aktualny->poprzedni; } } else { aktualny = aktualny->nastepny; } } aktualny = *poczatek; } printf("Posortowano wedlug grup.n"); } } void dodawanie_kontaktu(struct element** gora) { struct element* nowy; nowy = calloc(1, sizeof(struct element)); printf("Podaj imie, nazwisko, numer_telefonu i grupe (oddzielona spacjami):n"); scanf("%s %s %s %s", nowy->kontakt.imie, nowy->kontakt.nazwisko, nowy->kontakt.numer, nowy->kontakt.grupa); nowy->poprzedni = (*gora); nowy->nastepny = NULL; (*gora)->nastepny = nowy; (*gora) = nowy; } void wyszukiwanie_kontaktu(struct element* poczatek, int opcja) { char* tab; char* wyraz; char* wyraz2; int i = 0; int j; int numer = 1; struct element* aktualny; aktualny = calloc(1, sizeof(struct element)); tab = calloc(30, sizeof(char)); wyraz = calloc(30, sizeof(char)); wyraz2 = calloc(30, sizeof(char)); *(wyraz) = _getch(); *wyraz2 = *wyraz; while (*(wyraz + i) != 32) { printf("Aby zakonczyn wyszukiwanie kliknij spacjen"); aktualny = poczatek; if (*(wyraz + i) == 8 && i > 0) { *(wyraz + i) = '�'; *(wyraz + i - 1) = '�'; *(wyraz2 + i) = '�'; *(wyraz2 + i - 1) = '�'; i -= 2; } if (*(wyraz + i) > 64 && *(wyraz + i) < 91) { *(wyraz + i) = *(wyraz + i) + 32; } while (aktualny != NULL) { if (opcja == 1) { for (j = 0; j < sizeof(aktualny->kontakt.imie)/sizeof(char); j++) { if (aktualny->kontakt.imie[j] > 64 && aktualny->kontakt.imie[j] < 91) { aktualny->kontakt.imie[j] = aktualny->kontakt.imie[j] + 32; } } tab = strstr(aktualny->kontakt.imie, wyraz); /*Jeśli fragment zostanie znaleziony - tablicę znaków ( char * ) będącą częścią str1 od pierwszego wystąpienia str2 w str1, np. dla: char* tab; tab = strstr( "Alamakota", "ama" ); tab przyjmie wartość "amakota". - Jeśli fragment nie zostanie znaleziony – NULL;*/ aktualny->kontakt.imie[0] = aktualny->kontakt.imie[0] - 32; if (tab != NULL) { printf("%d)%s %s %s %sn", numer, aktualny->kontakt.imie, aktualny->kontakt.nazwisko, aktualny->kontakt.numer, aktualny->kontakt.grupa); numer += 1; } } if (opcja == 2) { for (j = 0; j < sizeof(aktualny->kontakt.nazwisko) / sizeof(char); j++) { if (aktualny->kontakt.nazwisko[j] > 64 && aktualny->kontakt.nazwisko[j] < 91) { aktualny->kontakt.nazwisko[j] = aktualny->kontakt.nazwisko[j] + 32; } } tab = strstr(aktualny->kontakt.nazwisko, wyraz); aktualny->kontakt.nazwisko[0] = aktualny->kontakt.nazwisko[0] - 32; if (tab != NULL) { printf("%d)%s %s %s %sn", numer, aktualny->kontakt.imie, aktualny->kontakt.nazwisko, aktualny->kontakt.numer, aktualny->kontakt.grupa); numer += 1; } } if (opcja == 3) { for (j = 0; j < sizeof(aktualny->kontakt.grupa) / sizeof(char); j++) { if (aktualny->kontakt.grupa[j] > 64 && aktualny->kontakt.grupa[j] < 91) { aktualny->kontakt.grupa[j] = aktualny->kontakt.grupa[j] + 32; } } tab = strstr(aktualny->kontakt.grupa, wyraz); if (tab != NULL) { printf("%d)%s %s %s %sn", numer, aktualny->kontakt.imie, aktualny->kontakt.nazwisko, aktualny->kontakt.numer, aktualny->kontakt.grupa); numer += 1; } } aktualny = aktualny->nastepny; } numer = 1; i += 1; printf("%s", wyraz2); *(wyraz + i) = _getch(); *(wyraz2 + i) = *(wyraz + i); system("cls"); } free(aktualny); free(wyraz); free(wyraz2); } void usuwanie_kontaktu(struct element** poczatek, int numer,struct element** gora) { struct element* aktualny; int i; aktualny = calloc(1, sizeof(struct element)); aktualny = *poczatek; for (i = 0; i < numer - 1; i++) { aktualny = aktualny->nastepny; if (aktualny == NULL) { printf("Podano zly numer.n"); return; } } if ((*aktualny).nastepny != NULL && (*aktualny).poprzedni != NULL) { (*aktualny).poprzedni->nastepny = (*aktualny).nastepny; (*aktualny).nastepny->poprzedni = (*aktualny).poprzedni; } if ((*aktualny).poprzedni == NULL && (*aktualny).nastepny == NULL) *poczatek=NULL; else { if ((*aktualny).poprzedni == NULL) { (*aktualny).nastepny->poprzedni = NULL; *poczatek = aktualny->nastepny; } if ((*aktualny).nastepny == NULL) { (*aktualny).poprzedni->nastepny = NULL; *gora = aktualny->poprzedni; } } free(aktualny); } void czyszczenie(struct element** poczatek, struct element**gora) { while ((*poczatek)->nastepny != NULL) { usuwanie_kontaktu(poczatek,1,gora); } free(*poczatek); } int main() { struct element* poczatek = NULL; struct element* gora = NULL; int x = 0; int sort = 0; int opcja = 0; int numer = 0; setlocale(LC_ALL, "polish_poland"); printf("Witaj w programie ksiazki telefonicznej.n"); while (x != 7) { printf("Menu:n"); printf("1)Wczytywanie ksiazki.n"); printf("2)Wyswietlanie ksiazki.n"); printf("3)Sortowanie kontaktow.n"); printf("4)Dodawanie kontaktow.n"); printf("5)Wyszukiwanie kontatkow.n"); printf("6)Usuwanie kontaktow.n"); printf("7)Zakonczenie programu.n"); if ((scanf("%d", &x) == 1) && x > 0 && x < 8) { switch (x) { case 1: wyczyscbufor(); system("cls"); wczytywanie_z_pliku(&poczatek,&gora); printf("Pomyslnie wczytano ksiazke.n"); break; case 2: wyczyscbufor(); system("cls"); if (poczatek == NULL) { printf("Nie ma wczytanej zadnej ksiazki.n"); } else { wyswietlanie_kontatkow(poczatek); printf("n"); } break; case 3: wyczyscbufor(); while (1) { system("cls"); if (poczatek == NULL) { printf("Nie ma wczytanej zadnej ksiazki.n"); break; } else { printf("Podaj ktore opcje sortowania chcesz wykoanc.n"); printf("1)Sortowanie alfabtetyczne imion.n"); printf("2)Sortowanie alfabetyczne nazwisk.n"); printf("3)Sortowanie alfabetyczne grup.n"); if (scanf("%d", &sort) == 1 && sort > 0 && sort < 4) { wyczyscbufor(); system("cls"); sortowanie(&poczatek,&gora, sort); break; } else { printf("Podano zla opcje. Sprobuj ponownien"); } } } break; case 4: wyczyscbufor(); system("cls"); if (poczatek == NULL) { printf("Nie ma wczytanej zadnej ksiazki.n"); } else { dodawanie_kontaktu(&gora); sortowanie(&poczatek,&gora, sort); printf("n"); printf("Dodano pomyslnie kontakt.n"); } break; case 5: wyczyscbufor(); system("cls"); if (poczatek == NULL) { printf("Nie ma wczytanej zadnej ksiazki.n"); } else { while (1) { printf("Podaj ktora opcje chcesz wybrac:n"); printf("1)Wyszukiwanie po imieniu.n"); printf("2)Wyszukiwanie po nazwisku.n"); printf("3)Wyszukiwanie po grupie.n"); if (scanf("%d", &opcja) == 1 && opcja > 0 && opcja < 4) { wyczyscbufor(); system("cls"); wyszukiwanie_kontaktu(poczatek, opcja); break; } else { wyczyscbufor(); system("cls"); printf("Podano zla opcje. Sprobuj ponownie.n"); } } } break; case 6: wyczyscbufor(); system("cls"); while (1) { if (poczatek == NULL) { printf("Nie ma wczytanej zadnej ksiazki.nn"); break; } else { wyswietlanie_kontatkow(poczatek); printf("Podaj ktory kontakt chcesz usunac:n"); if (scanf("%d", &numer) == 1 && numer > 0) { wyczyscbufor(); system("cls"); usuwanie_kontaktu(&poczatek, numer,&gora); printf("Kontkat zostal usuniety pomyslnie.n"); break; } else { wyczyscbufor(); system("cls"); printf("Podano zly numer.n"); } } } break; case 7: wyczyscbufor(); system("cls"); if (poczatek != NULL) { czyszczenie(&poczatek,&gora); printf("Wyczyszczono kontaktyn"); } break; } } else { wyczyscbufor(); system("cls"); printf("Podano zla opcje. Sprobuj jeszcze raz.n"); } } printf("Koniec programu.n"); }