#include<stdio.h>
#include<stdlib.h>
#include<locale.h>
#include<string.h>
#include<conio.h>
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;
}
}
{
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;
}
}
}
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++;
}
}
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;
*(wyraz + i) = _getch();
*(wyraz2 + i) = *(wyraz + i);
}
}
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)
{
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;
}
}
}
void czyszczenie(struct element** poczatek, struct element**gora)
{
while ((*poczatek)->nastepny != NULL)
{
usuwanie_kontaktu(poczatek,1,gora);
}
}
int main()
{
struct element* poczatek = NULL;
struct element* gora = NULL;
int x = 0;
int sort = 0;
int opcja = 0;
int numer = 0;
printf("Witaj w programie ksiazki telefonicznej.n");
while (x != 7)
{
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();
wczytywanie_z_pliku(&poczatek,&gora);
printf("Pomyslnie wczytano ksiazke.n");
break;
case 2:
wyczyscbufor();
if (poczatek == NULL)
{
printf("Nie ma wczytanej zadnej ksiazki.n");
}
else
{
wyswietlanie_kontatkow(poczatek);
}
break;
case 3:
wyczyscbufor();
while (1)
{
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();
sortowanie(&poczatek,&gora, sort);
break;
}
else
{
printf("Podano zla opcje. Sprobuj ponownien");
}
}
}
break;
case 4:
wyczyscbufor();
if (poczatek == NULL)
{
printf("Nie ma wczytanej zadnej ksiazki.n");
}
else
{
dodawanie_kontaktu(&gora);
sortowanie(&poczatek,&gora, sort);
printf("Dodano pomyslnie kontakt.n");
}
break;
case 5:
wyczyscbufor();
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();
wyszukiwanie_kontaktu(poczatek, opcja);
break;
}
else
{
wyczyscbufor();
printf("Podano zla opcje. Sprobuj ponownie.n");
}
}
}
break;
case 6:
wyczyscbufor();
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();
usuwanie_kontaktu(&poczatek, numer,&gora);
printf("Kontkat zostal usuniety pomyslnie.n");
break;
}
else
{
wyczyscbufor();
}
}
}
break;
case 7:
wyczyscbufor();
if (poczatek != NULL)
{
czyszczenie(&poczatek,&gora);
printf("Wyczyszczono kontaktyn");
}
break;
}
}
else
{
wyczyscbufor();
printf("Podano zla opcje. Sprobuj jeszcze raz.n");
}
}
}