Baza danych studentów w oparciu o listę dwukierunkową w C++. Sortowanie wyników QuickSort, wyszukiwanie poprzez dopasowanie wzorca. Zapis do pliku.

[b]Projekt bazy danych studentów przy użyciu listy dwukierunkowej wykonany w C++ przy użyciu funkcji i klas. Projekt dla I roku studiów Informatycznych. Projekt uruchamiany pod Visual Studio 2008.[/b] Szczególne funkcje programu: automatyczne ładowanie bazy po uruchomieniu programu przy wyjściu z programu jesteśmy pytani o to czy zapisać zmiany w bazie przy zapisywaniu bazy danych możemy nadpisać rekordy w pliku txt rekordami z bazy znajdującej się w pamięci programu lub możemy dopisać rekordy do bazy txt.

[b]Projekt bazy danych studentów przy użyciu listy dwukierunkowej wykonany w C++ przy użyciu funkcji i klas. Projekt dla I roku studiów Informatycznych. Projekt uruchamiany pod Visual Studio 2008.[/b]

Szczególne funkcje programu:

  • automatyczne ładowanie bazy po uruchomieniu programu

  • przy wyjściu z programu jesteśmy pytani o to czy zapisać zmiany w bazie

  • przy zapisywaniu bazy danych możemy nadpisać rekordy w pliku txt rekordami z bazy znajdującej się w pamięci programu lub możemy dopisać rekordy do bazy txt. Dopisanie rekordów oznacza przydzielenie im nowych numerów ID tak aby nie powtarzały się z tymi które już istnieją w pliku txt.

  • Kasowanie bazy: albo tej w pamięci programu albo tej w pliku txt

  • Dodawanie rekordów: [b]możemy dodawać je na początek listy lub na koniec[/b] (tak jak to powinno funkcjonować według idei listy dwukierunkowej)

  • Usuwanie rekordu: Przed usunięciem wyświetlana jest lista rekordów abyśmy mogli poznać ID rekordu który chcemy usunąć.

  • [b]Edycja rekordu[/b]: Podczas edycji możemy pominąć wpisywanie nowego pola poprzez podanie słowa: “ok”

  • Podczas dodawania lub edycji rekordu sprawdzane jest czy podajemy poprawny ID lub rok studiów jako liczbę. Inne pola także są sprawdzane np. jeśli podamy puste pole to zostaniemy poproszeni o podanie tekstu ponownie

  • Sortowanie wyników przy użyciu [b]QuickSort[/b]. Wyniki możemy sortować po poszczególnych polach. Mamy możliwość wybrania sposobu wyświetlenia ich od najmniejszego do największego (ASC), od największego do najmniejszego (DESC)

  • Po posortowaniu rekordów mamy możliwość zapamiętania tej kolejności wyników na stałe w pamięci programu.

  • Wyszukiwanie w bazie następuje po wskazanym kryterium. Jeśli wyszukujemy po tekście np. imie, nazwisko itd to [b]wyszukiwanie następuje poprzez dopasowanie wzorca[/b]. Np. jeśli wpiszemy aby wyszukiwać po kierunku studiów i podamy jako wzorzec “inf” to otrzymamy rekordy pasujące do niego np. kierunek informatyka

  • [b]Wyniki wyszukiwania możemy zapisać do pliku txt[/b]. Zapamiętana jest data wyszukiwania, kryterium i wzorzec według którego szukaliśmy rekordów, liczba rekordów.

[b]Główny plik programu: Baza danych studentow.cpp[/b] [code=cpp] /* The MIT License

Copyright (c) 2010 Webook.pl

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ // Baza danych studentow.cpp : Defines the entry point for the console application.

#include “stdafx.h” #include #include #include #include <conio.h> // zawiera funkcja getch() #include // time() #include <Windows.h> //zawiera funkcje SetConsoleTextAttribute #include “CBazaDanych.h”

using namespace std;

//=============================================================

//deklaracja funkcji globalnych void color(int); void clear_screen(); void menu_glowne();

//=============================================================

//tworzymy obiekt db naszej bazy danych CBazaDanych db;

//============================================================= //=============================================================

int _tmain(int argc, _TCHAR* argv[]) { db.WczytajBazeZPliku(0, 0); //ladujemy baze danych przy uruchomieniu programu, 0- nie wyswietlamy komunikatu czy wczytac baze, 0-nie kasujemy baze, bo przy pierwszym ladowaniu baza jest juz pusta menu_glowne(); db.SaveAutoIncrement(); //zapisanie wartosci ostatnio dodanego ID return 0; }

//============================================================= //=============================================================

void color(int i) { // funkcja wlacza kolorowanie napisow drukowanych przez cout if(i==1) { // czerwony SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_INTENSITY); } else if(i==2) { // bialy SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); } else if(i==3) { // zielony SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN); } else if(i==4) { // niebieski SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_BLUE); } else if(i==5) { // czarno na bialym SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), BACKGROUND_INTENSITY | FOREGROUND_INTENSITY | BACKGROUND_GREEN | BACKGROUND_BLUE); } else { // domyslny kolor tekstu w konsoli SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); } }

//=============================================================

void clear_screen() { system(“cls”); cout«"====== Baza danych studentow v1.0 25.05.2010 Webook.pl ======n"; db.ReturnAutoIncrementAndLiczbaRekordow();

color(1);
	cout<<"1";
color(0);
cout<<" - wczytaj baze z pliku, ";

color(1);
cout<<"2";
color(0);	
cout<<" - zapisz baze, ";

color(1);
cout<<"3";
color(0);
cout<<" - skasuj bazen";

color(3);
cout<<"4";
color(0);
cout<<" - dodaj nowy rekord, ";

color(3);
cout<<"5";
color(0);
cout<<" - usun rekord, ";

color(3);
cout<<"6";
color(0);
cout<<" - edytuj rekordn";

color(4);
cout<<"7";
color(0);
cout<<" - wyswietl rekordy, ";

color(4);
cout<<"8";
color(0);
cout<<" - posortuj rekordy, ";

color(4);
cout<<"9";
color(0);
cout<<" - wyszukaj rekordyn";

color(2);
cout<<"k";
color(0);
cout<<" - koniecnn";

}

//=============================================================

void menu_glowne() { clear_screen();

char nawigacja;
bool wybrano_poprawny_klawisz = 0;
bool exit = 0;

do {
	nawigacja = _getch(); // pobiera znak tak dlugo az zostana wcisniete strzalki gora/dol lub enter
	switch(nawigacja) {
		case '1':
			db.WczytajBazeZPliku(1, 1);//1-wyswietl komunikat z pytaniem czy zaladowac baze, 1-uruchom funkcje czyszczaca baze przed zaladowaniem rekordow z pliku
			wybrano_poprawny_klawisz = 1;
			break;
		case '2':
			db.ZapiszBazeDoPliku();
			wybrano_poprawny_klawisz = 1;
			break;
		case '3':
			cout<<"Czy aby na pewno chcesz skasowac baze danych? Wybierz dzialanie:n"
				<<"1 - Skasuj baze danych zawarta w pamieci programun"
				<<"2 - Skasuj tylko baze danych w pliku txtn"
				<<"3 - Anulujnn";
			char nawigacja_kasuj;
			do {					
				nawigacja_kasuj = _getch();
			} while(nawigacja_kasuj != '1' && nawigacja_kasuj != '2' && nawigacja_kasuj != '3');				
			if(nawigacja_kasuj == '1') {
				db.SkasujBaze(1);//wyswietlamy komunikaty o udanym skasowaniu oraz zapytanie czy zapisac rowniez zmiany w bazie txt
			} else if(nawigacja_kasuj == '2') {
				db.WyczyscBazeDanychWPliku();
				cout<<"Baza danych w pliku txt zostala wyczyszczona!";
			} else {
				cout<<"Anulowano kasowanie bazy...";
			}
			wybrano_poprawny_klawisz = 1;
			break;
		case '4':
			cout<<"1 - Dodaj element na poczatek listyn"
				<<"2 - Dodaj element na koniec listyn"
				<<"3 - Anulujnn";
			char nawigacja_dodaj;
			do {					
				nawigacja_dodaj = _getch();
			} while(nawigacja_dodaj != '1' && nawigacja_dodaj != '2' && nawigacja_dodaj != '3');				
			if(nawigacja_dodaj == '1') {
				db.DodajNaPoczatek();
			} else if(nawigacja_dodaj == '2') {
				db.DodajNaKoniec();
			} else cout<<"Anulowano...";
			wybrano_poprawny_klawisz = 1;
			break;
		case '5':
			db.UsunRekord();
			wybrano_poprawny_klawisz = 1;
			break;
		case '6':
			db.EdytujRekord();
			wybrano_poprawny_klawisz = 1;
			break;
		case '7':
			db.WyswietlRekordy();
			wybrano_poprawny_klawisz = 1;
			break;
		case '8':
			db.SortujRekordy();
			wybrano_poprawny_klawisz = 1;
			break;
		case '9':
			db.WyszukajRekordy();
			wybrano_poprawny_klawisz = 1;
			break;
		case 'k':
			cout<<"UWAGA!! Zanim wyjdziesz z programu:n ";
			db.ZapiszBazeDoPliku(1,0);//0 oznaczacza ze nie pytamy sie czy zaladowac do pamieci programu zaktualizowana baze
			wybrano_poprawny_klawisz = 1;
			exit = 1;
			break;
	}		
} while(wybrano_poprawny_klawisz==0);
if(exit!=1) {
	cout<<"nn";
	system("pause");
	menu_glowne();
}

} [/code]

[b]Plik nagłówkowy: CBazaDanych.h[/b] [code=cpp] /* The MIT License

Copyright (c) 2010 Webook.pl

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include “stdafx.h” #include #include #include <conio.h> #include

using namespace std;

//=============================================================

// struktura listy dwukierunkowej struct element { element* next; element* prev; int id; string imie; string nazwisko; int rok_studiow; string kierunek; };

// deklaracja i definicje metod klasy bazy danych //=============================================================

class CBazaDanych { private: //przechowuje id rekordu ostatnio dodanego, dzieki temu wiemy jaki nastepny ID przypisac dla kolejnego rekordu int AutoIncrement; int LiczbaRekordow; //zawiera liczbe rekordow akutalnie przechowywanych na liscie element* lista_poczatek; //wskaznik na pierwszy element listy element* lista_koniec; //wskaznik na ostatni element listy const char* URL_Baza; //adres pliku z zapisana baza const char* URL_AutoIncrement; //adres pliku przechowujacego informacje o ostatnio dodanym ID const char* URL_LogWyszukiwanie;

	// Metody prywatne
	void DodajRekordBezposrednio(element* &, element* &, string, string, string, string, string);
	void Dodaj(element* &, element* &, int);
	void CountLiczbaRekordow();
	void QuickSort(element [], int, int, string, int);
	int StringFind(string, string, int, int); //funkcja wyszukujaca czy w tekscie wystepuje wzorzec, zwraca 1-tak
	string IntToString(int);

public:
	// konstruktor
	CBazaDanych();		
	// destruktor
	~CBazaDanych();
	
	// Metody publiczne
	void WczytajBazeZPliku(bool, bool);		
	void ZapiszBazeDoPliku(int WyswietlKomunikat=1, int WyswietlKomunikat2=1);
	void SkasujBaze(int WyswietlKomunikat=0);
	void WyczyscBazeDanychWPliku();		
	void SaveAutoIncrement();
	void ReturnAutoIncrementAndLiczbaRekordow();				
	void DodajNaPoczatek();
	void DodajNaKoniec();
	void UsunRekord(int WlaczKomunikaty=1, int ID_delete=0);
	void EdytujRekord();		
	void WyswietlRekordy();
	void WyszukajRekordy();
	void SortujRekordy();		

}; [/code]

[b]Plik: CBazaDanych.cpp[/b] [code=cpp] /* The MIT License

Copyright (c) 2010 Webook.pl

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include “stdafx.h” #include #include #include <conio.h> #include #include <time.h> #include #include “CBazaDanych.h”

using namespace std;

//=============================================================

// konstruktor CBazaDanych::CBazaDanych() { //definicja zmienych prywatnych this->URL_Baza = “baza_log/BazaStudentow.txt”; this->URL_AutoIncrement = “baza_log/AutoIncrement.txt”; this->URL_LogWyszukiwanie = “baza_log/log_wyszukiwanie.txt”;

//inicjalizacja wskaznikow prywatych
this->lista_poczatek = NULL;
this->lista_koniec = NULL;
this->LiczbaRekordow = 0;

//ładujemy informacje o numerze ostatniego ID z pliku konfiguracyjnego
// przed odczytem otwieramy plik tak jakbysmy chcieli cos dopisac ale nic nie dopiszemy dzieki temu nieistniejacy plik zostanie utworzony
fstream plik;
plik.open(this->URL_AutoIncrement, ios::app);		
plik.close();

// odczyt
ifstream ifile(this->URL_AutoIncrement);	
string plik_au;						
while(!ifile.eof()) {
	getline(ifile,plik_au);
	if(plik_au.length() == 0) {
		this->AutoIncrement = 0;
	} else {
		this->AutoIncrement = atoi(plik_au.c_str()); //przypisanie do zmiennej prywatnej informacji o ostatnim ID
		//funkcja atoi, HOWTO: http://4programmers.net/C/Konwersje_int_na_string_i_string_na_int#id-string-na-int
	}
}
ifile.close();

}

//=============================================================

CBazaDanych::~CBazaDanych() { SaveAutoIncrement(); }

//=============================================================

void CBazaDanych::SaveAutoIncrement() { fstream plik; plik.open(this->URL_AutoIncrement, ios::out); plik«this->AutoIncrement; plik.close(); }

//=============================================================

void CBazaDanych::ReturnAutoIncrementAndLiczbaRekordow() { CountLiczbaRekordow();//zliczamy liczbe rekordow przed wyswietleniem ich cout«"====== ID ostatnio dodanego rekordu: “«this->AutoIncrement«”, Rekordow w pamieci: “«this->LiczbaRekordow«“n”; }

//=============================================================

void CBazaDanych::CountLiczbaRekordow() { //zliczamy liczbe rekordow this->LiczbaRekordow = 0; if(this->lista_poczatek != NULL) { element* temp = this->lista_poczatek; while(temp != NULL) { this->LiczbaRekordow++; temp = temp->next; } } }

//=============================================================

// w_l - wskaznik pierwszego elementu na calej liscie! // w_k - wskaznik konca listy // gdzie_dodac==1 dodamy na koniec listy, a gdy==0 to na poczatek void CBazaDanych::Dodaj(element* &w_l, element* &w_k, int gdzie_dodac) { element* wn = new element;

//zwiekszamy wartosci zmiennych prywatynch
this->AutoIncrement++; 
this->LiczbaRekordow++;
	
wn->id = this->AutoIncrement;
	
cout<<"Podaj imie: ";
getline(cin,wn->imie);
while(wn->imie == "") {
	cout<<"Podales pusty ciag znakow! Podaj imie: ";
	getline(cin,wn->imie);
}
	
cout<<"Podaj nazwisko: "; 
getline(cin,wn->nazwisko);
while(wn->nazwisko == "") {
	cout<<"Podales pusty ciag znakow! Podaj nazwisko: ";
	getline(cin,wn->nazwisko);
}

cout<<"Podaj rok studiow: "; 	
string rok;
int rok_int;
getline(cin,rok); //ładujemy do stringa rok
rok_int = atoi(rok.c_str()); //konwersja stringa na int
while(rok == "" || rok_int == 0) {//jesli nie podano roku lub podany rok to liczba 0, np. jesli ktos zamiast liczby poda slowo to ono jest konwertowane na 0 wiec w takim przypadku ponownie zapytamy o podanie wlasciwego roku
	if(rok=="") {//podano pusty ciag znakow zamiast roku
		cout<<"Podales pusty rok! Podaj nowy rok studiow: ";						
	} else { //podano ciag znakow o jakiejs dlugosci ktory zostal zamieniony na liczbe 0
		cout<<"Podales ciag znakow zamiast roku liczbowego! Podaj nowy rok studiow: ";
	}
	getline(cin,rok);
	rok_int = atoi(rok.c_str());
}
wn->rok_studiow = rok_int; 

cout<<"Podaj kierunek: "; 
getline(cin,wn->kierunek);
while(wn->kierunek == "") {
	cout<<"Podales pusty ciag znakow! Podaj kierunek: ";
	getline(cin,wn->kierunek);
}

if(gdzie_dodac == 1) { //gdzie_dodac==1 to dodajemy na koniec listy
	wn->prev = w_k; //poprzedni element przed tym ktory teraz dodalismy to w_k czyli obecny koniec listy
	wn->next = NULL; // nastepny element to NULL bo wlasnie dodajemy ostatni element i po nim nic juz nie ma
	
	if(w_k != NULL) {
		w_k->next = wn;			
	} else { //w_k==NULL co znaczy ze dodajemy pierwszy element!
		w_l = wn;
	}
	w_k = wn; //teraz ustawiamy ze nowym elementem koncowym jest nasze wn (wskaznik nowy do elementu ktory wlasnie dodalismy)
	
	cout<<"Dodano na koniec listy!";

} else { //gdzie_dodac==0 to dodajemy na poczatek listy
	wn->prev = NULL; //pierwszy element listy nigdy nie ma poprzednika
	wn->next = w_l; //nastepnym elementem listy staje sie wskaznik ktory dotychczas pokazywal na poczatek listy
	
	//aktualizujemy wskaznik ktory teraz staje sie drugim elementem listy aby wiedzial ze ma przed soba nasze wn
	if(w_l != NULL) {
		w_l->prev = wn;
	} else { //tylko gdy po raz pierwszy dodajemy rekord to ten dodany wlasnie element staje sie koncowym
		w_k = wn;
	}
	w_l = wn; //naszym nowym poczatkiem listy staje sie wn
	cout<<"Dodano na poczatek listy!";
}

}

//=============================================================

//funkcja przyjmujaca jako argumenty stringi, dodajemy nowy rekord na koniec listy void CBazaDanych::DodajRekordBezposrednio(element* &w_l, element* &w_k, string id, string i, string n, string r, string k) { element* wn = new element;

int id_int = atoi(id.c_str()); //konwersja string na int
wn->id = id_int;
wn->imie = i;
wn->nazwisko = n;
int rok_studiow = atoi(r.c_str()); //konwersja string na int
wn->rok_studiow = rok_studiow;
wn->kierunek = k;

//dodajemy na koniec listy
wn->prev = w_k; //poprzedni element przed tym ktory teraz dodalismy to w_k czyli obecny koniec listy
wn->next = NULL; // nastepny element to NULL bo wlasnie dodajemy ostatni element i po nim nic juz nie ma

if(w_k != NULL) {
	w_k->next = wn;			
} else { //w_k==NULL co znaczy ze dodajemy pierwszy element!
	w_l = wn;
}
w_k = wn; //teraz ustawiamy ze nowym elementem koncowym jest nasze wn (wskaznik nowy do elementu ktory wlasnie dodalismy)
cout<<"Dodano rekord: "<<id<<", "<<i<<", "<<n<<", "<<r<<", "<<k<<"n";
this->LiczbaRekordow++;

}

//=============================================================

void CBazaDanych::DodajNaPoczatek() { CBazaDanych::Dodaj(this->lista_poczatek, this->lista_koniec, 0); }

//=============================================================

void CBazaDanych::DodajNaKoniec() { CBazaDanych::Dodaj(this->lista_poczatek, this->lista_koniec, 1); }

//=============================================================

// w_l - wskaznik na pierwszy element listy void CBazaDanych::WyswietlRekordy() { if(this->lista_poczatek == NULL) { cout«“Lista jest pusta!”;

} else {
	element* temp = this->lista_poczatek;
	while(temp != NULL)
	{
		cout<<"ID:          "<<temp->id<<"n"
			<<"Imie:        "<<temp->imie<<"n"
			<<"Nazwisko:    "<<temp->nazwisko<<"n"
			<<"Rok studiow: "<<temp->rok_studiow<<"n"
			<<"Kierunek:    "<<temp->kierunek<<"n"
			<<"==========================================n";

		temp = temp->next;
	}		
}

}

//=============================================================

//domyslne parametry okreslone w CBazaDanych.h //int WlaczKomunikaty=1, int ID_delete=0 void CBazaDanych::UsunRekord(int WlaczKomunikaty, int ID_delete) { if(WlaczKomunikaty) WyswietlRekordy();

if(this->lista_poczatek == NULL && this->lista_koniec == NULL)
{
	if(WlaczKomunikaty)	cout<<" Nie ma co usuwac!";
}
else 
{	
	int id;
	if(WlaczKomunikaty) {
		cout<<"nPodaj ID rekordu ktory usunac: ";
		string get;
		getline(cin,get);
		id = atoi(get.c_str()); //konwersja string na int
	} else {
		id = ID_delete; //usuwamy id ktory przeslalismy jako argument funkcji
	}

	element* temp = this->lista_poczatek;
	int znaleziono = 0; //domyslana zmienna okreslajaca ze nie znaleziono elementu do usuniecia
	element* temp_usun;
	while(temp != NULL)
	{
		if(temp->id == id) {
			element* temp_prev = temp->prev; //1 
			element* temp_next = temp->next; //3
			
			//załóżmy że mamy element 1, 2, 3. Element 2 usuwamy.
			// Poniżej elementowi 1 ustawiamy iz po nim jest 3
			if(temp_prev != NULL) {
				temp_prev->next = temp->next; //ustawiamy ze po elemencie 1 jest 3
				if(temp->next == NULL) { //to oznacza ze ostatni element nie istnieje wiec element 2 ktory teraz usuwamy  jest ostatnim a wiec element 1 bedzie teraz ostatnim wiec musimy mu ustawic ze dla naszej listy wskaznik ostatni to nasz element 1
					this->lista_koniec = temp_prev;
				}
			}
			// Poniżej elementowi 3 ustawiamy iz go poprzedza 1
			if(temp_next != NULL) {
				temp_next->prev = temp->prev;
				if(temp->prev == NULL) { //jezeli nie istnieje element 1 to ustawiamy ze element 3 staje sie poczatkiem listy bo skasowalismy element 2
					this->lista_poczatek = temp_next;
				}
			}
			
			//kasujemy element 2
			temp_usun = temp;
			if(WlaczKomunikaty) cout<<"nUsunieto rekord o ID: "<<temp_usun->id;
			delete temp_usun;
			//cout<<"ntemp_usun: "<<temp_usun->imie;
			//cout<<"ntemp: "<<temp->imie;
			
			this->LiczbaRekordow--; //zmniejszamy liczbe rekordow
		
			if(this->LiczbaRekordow == 0) {
				//skasowalismy wszystkie rekordy wiec ustawiamy na NULL wartosci
				this->lista_poczatek = NULL;
				this->lista_koniec = NULL;
			}
			
			znaleziono = 1; //znaleziono rekord do usuniecia
			
			break; //przerwanie pętli ponieważ znalezlismy juz element do usuniecia

		} else {
			temp = temp->next;
		}
	}

	if(znaleziono == 0 && WlaczKomunikaty) {
		cout<<"nNie znaleziono rekordu do usuniecia!";
	}
}

}

//=============================================================

void CBazaDanych::EdytujRekord() { WyswietlRekordy();

if(this->lista_poczatek == NULL && this->lista_koniec == NULL)
{
	cout<<" Nie ma co edytowac!";
}
else 
{	
	cout<<"nPodaj ID rekordu ktory chcesz edytowac: ";
	string get;//zmienna pomocnicza
	getline(cin,get);
	int id = atoi(get.c_str()); //konwersja string na int
	int znaleziono = 0; //domyslana zmienna okreslajaca ze nie znaleziono elementu do edycji
	element* temp = this->lista_poczatek;	
	while(temp != NULL)
	{
		if(temp->id == id) {
			
			cout<<"n========= Rekord ktory edytujesz =========n"				
				<<"ID: "<<temp->id<<"n"
				<<"Imie: "<<temp->imie<<"n"
				<<"Nazwisko: "<<temp->nazwisko<<"n"
				<<"Rok studiow: "<<temp->rok_studiow<<"n"
				<<"Kierunek: "<<temp->kierunek<<"n"
				<<"==========================================nn"
				<<"UWAGA: Wpisz "ok" aby nie modyfikowac danego pola!nn";
			
			cout<<"Podaj nowe imie: "; 
			getline(cin,get);
			while(get == "") {
				cout<<"Podales pusty ciag znakow! Podaj nowe imie: ";
				getline(cin,get);
			}
			if(get != "ok") { //jesli podano cos innego niz ok to zapisujemy zmiane
				temp->imie = get;
			}
	
			cout<<"Podaj nowe nazwisko: "; 
			getline(cin,get);
			while(get == "") {
				cout<<"Podales pusty ciag znakow! Podaj nowe nazwisko: ";
				getline(cin,get);
			}
			if(get != "ok") {
				temp->nazwisko = get;
			}
	
			cout<<"Podaj nowy rok studiow: "; 	
			string rok;
			int rok_int;
			getline(cin,rok); //ładujemy do stringa rok	
			rok_int = atoi(rok.c_str()); //konwersja stringa na int
			while((rok == "" || rok_int == 0) && rok !="ok") {//jesli nie podano roku lub podany rok to liczba 0, np. jesli ktos zamiast liczby poda slowo to ono jest konwertowane na 0 wiec w takim przypadku ponownie zapytamy o podanie wlasciwego roku. Jesli podano slowo ok to nie prosimy ponownie o rok
				if(rok=="") {//podano pusty ciag znakow zamiast roku
					cout<<"Podales pusty rok! Podaj nowy rok studiow: ";						
				} else { //podano ciag znakow o jakiejs dlugosci ktory zostal zamieniony na liczbe 0
					cout<<"Podales ciag znakow zamiast roku liczbowego! Podaj nowy rok studiow: ";
				}
				getline(cin,rok);
				rok_int = atoi(rok.c_str());
			}
			if(rok != "ok") {//jesli podano ok to nie zmieniamy roku
				temp->rok_studiow = rok_int;
			}

			cout<<"Podaj nowy kierunek: "; 
			getline(cin,get);
			while(get == "") {
				cout<<"Podales pusty ciag znakow! Podaj nowy kierunek: ";
				getline(cin,get);
			}
			if(get != "ok") {
				temp->kierunek = get;
			}

			cout<<"nPomyslnie zapisano zmiany!";
			
			znaleziono = 1; //znaleziono rekord do edycji
			break; //przerwanie petli bo znalezlismy juz element do edycji
		} else {
			temp = temp->next;
		}
	}
	if(znaleziono == 0) {
		cout<<"nNie znaleziono rekordu do edycji!";
	}
}

}

//=============================================================

//int WyswietlKomunikat=1 //domyslnie wyswietlamy ten komunikat //WyswietlKomunikat2 = 1 void CBazaDanych::ZapiszBazeDoPliku(int WyswietlKomunikat, int WyswietlKomunikat2) { element* temp = this->lista_poczatek; if(temp == NULL) { if(WyswietlKomunikat) {//ten komunikat wyswietlamy podczas akcji zapisu do pliku, natomiast gdy uzytkownik uruchamia kasowanie bazy danych to pozniej wyswietlimy tylko same odpowiedzy czy chce rowniez skasowac baze txt. Nie wyswietlamy ponizszego komunikatu poniewaz juz w metodzie SkasujBaze jest wyswietlany komunikat z pytaniem cout«“nBrak rekordow w bazie ktore by mozna zapisac!n” «“A moze chcesz wyczyscic baze danych w pliku txt?n”; }

	cout<<"1 - Tak, wyczysc baze danych w pliku txtn"
		<<"2 - Nien";
	char nawigacja;
	do {					
		nawigacja = _getch();
	} while(nawigacja != '1' && nawigacja != '2');
	if(nawigacja == '1') {
		WyczyscBazeDanychWPliku();
		cout<<"Baza danych w pliku txt zostala wyczyszczona!";
	} else {
		cout<<"Baza danych w pliku txt pozostala nienaruszona.";
	}

} else {

	cout<<"nCzy chcesz zapisac liste rekordow do bazy w pliku txt?n"
		<<"1 - Zapisz baze do pliku (obecne dane w pliku zostana nadpisane)n"
		<<"2 - Zapisz baze do pliku poprzez dopisanie nowych rekordown"
		<<"3 - Nie zapisuj bazyn";
	
	char nawigacja;
	do {					
		nawigacja = _getch();
	} while(nawigacja != '1' && nawigacja != '2' && nawigacja != '3');				
	
	fstream plik;
	if(nawigacja == '1') {			
		plik.open(this->URL_Baza, ios::out); //ustawiamy tryb nadpisania pliku
	} else if(nawigacja == '2') {
		plik.open(this->URL_Baza, ios::app); //ustawiamy tryb dopisywania do pliku
	} else {
		cout<<"nBaza nie zostanie zapisana!";
	}

	//zapisujemy dane w pliku
	if(nawigacja == '1' || nawigacja == '2')
	{			
	
		cout<<"nTrwa zapisywanie...n";
		if(nawigacja == '2') {
			cout<<"nWybrales opcje dopisania rekordow do bazy.n"
				<<"Aby uniknac dublowania sie numerow ID, rekordy z pamieci programun"
				<<"otrzymaja nowe ID, ktore bedzie wieksze niz rekordow w bazie txtnn";
		}
		int tempID;			
		while(temp != NULL)
		{
			/* jesli dopisujemy rekordy do bazy to zmieniamy tym rekordom ID nawieksze 
			niz posiadaja rekordy w pliku txt aby uniknac sytuacji ze dwa rekordy maja 
			w bazie txt ten sam ID.
			*/
			if(nawigacja == '2') {
				//nadajemy rekordom nowe ID, wieksze od ostatnio dodanych ID w bazie aby uniknac sytuacji powtarzania sie ID rekordow w bazie
				//jednoczesnie robimy to przez preinkrementacje aby zwiekszyc wartosc AutoIncrement
				tempID = ++AutoIncrement;					
				cout<<"Zapisano rekord o ID="<<temp->id<<" w bazie txt i w pamieci programu pod nowym ID: "<<tempID<<"n";
				temp->id = tempID; //ID z pamieci programu zmieniamy na nowe ID ktore bedzie w bazie aby zachowac synchornizacje numerow ID
			} else {
				tempID = temp->id;
				cout<<"Zapisano rekord o ID="<<temp->id<<"n";
			}
			//wykonanie zapisu do pliku
			plik<<temp->id<<endl;
			plik<<temp->imie<<endl;
			plik<<temp->nazwisko<<endl;
			plik<<temp->rok_studiow<<endl;
			plik<<temp->kierunek<<endl;
			
			temp = temp->next;				
		}
		plik.close();
		
		SaveAutoIncrement(); //zapisujemy ID ostatnio dodanego rekordu

		if(nawigacja == '1') {
			cout<<"Pomyslnie nadpisano baze danych nowymi rekordami!";
		} else { //2
			cout<<"Pomyslnie dopisano rekordy do bazy danych!nn";
			/*trzeba teraz jeszcze zaktualizowac pamiec programu o rekordy ktore sa w bazie txt
			Mianowicie dane rekordy z pamieci dopisalismy do pliku txt zmieniajac im ID tak aby nie dublowac numerow ID
			z pliku txt. Teraz w pliku txt mamy jakies rekordy ktore juz tam byly plus rekordy ktore wlasnie dopisalismy.
			Dlatego wykonujemy teraz zaladowanie do pamieci programu calej bazy txt aby w pamieci miec to samo co w pliku txt
			*/
			if(WyswietlKomunikat2) {
				cout<<"UWAGA: Teraz powinienes zsynchronizowac zawartosc pamieci programu z baza txt.n"
					<<"Jesli chcesz to zrobic to po prostu zgodz sie na zaladowanie bazy z pliku:n";
				WczytajBazeZPliku(1, 1); //1-wyswietlamy komunikatu czy wczytac baze, 1-kasujemy baze w pamieci programu po czym ladujemy z pliku
			}
		}
	}
}

}

//=============================================================

void CBazaDanych::WyczyscBazeDanychWPliku() { fstream plik; plik.open(this->URL_Baza, ios::out); //ustawiamy tryb nadpisania pliku plik«”"; plik.close(); SaveAutoIncrement(); //zapisujemy ID ostatnio dodanego rekordu }

//=============================================================

void CBazaDanych::WczytajBazeZPliku(bool komunikat, bool czy_kasowac) { bool zaladuj_baze; if(komunikat == 1) //wyswietl komunikat z pytaniem czy zaladowac baze { cout«“Czy chcesz wczytac baze danych z pliku do pamieci programu?n” «"(Baza zawarta w pamieci programu zostanie nadpisana baza z pliku)n" «“1 - Wczytaj baze z plikun” «“2 - Anulujnn”; char nawigacja_dodaj; do { nawigacja_dodaj = _getch(); } while(nawigacja_dodaj != ‘1’ && nawigacja_dodaj != ‘2’);

	if(nawigacja_dodaj == '1') {
		zaladuj_baze = 1;
		cout<<"Wczytano!n";
	} else {
		zaladuj_baze = 0;
		cout<<"Anulowano wczytywanie bazy z pliku...";
	}
} else { // nie wyswietlamy komunikatu i odrazu ładujemy automatycznie baze
	zaladuj_baze = 1;
}

if(zaladuj_baze) {
	//skasowanie obecnej bazy w pamieci programu
	//jesli ladujemy baze przy pierwszym uruhcomieniu programu to nie uruchamiamy funkcji kasujacej
	if(czy_kasowac == 1) { //true = uruchom funkcje kasujaca baze
		SkasujBaze();
	}


	// odczyt bazy
	ifstream ifile(this->URL_Baza);		
	
	string tab[5]; //tablica zawierajaca 5 wierszy z kazdym polem informacji z bazy txt
	string wiersz;		
	int l=1; //liczba linii	
	while(!ifile.eof()) {
		getline(ifile,wiersz);			
		
		//cout<<l<<": "<<wiersz<<endl;
					
		if(wiersz!="")
		{							
			if(l%5==0) {
				tab[4] = wiersz; //tab[4] bo indexy od 0 są
			} else if(l%4==0) {
				tab[3] = wiersz;
			} else if(l%3==0) {
				tab[2] = wiersz;
			} else if(l%2==0) {
				tab[1] = wiersz;
			} else if(l%1==0) {
				tab[0] = wiersz;
			}
		}
		if(l%5==0) {				
			DodajRekordBezposrednio(this->lista_poczatek, this->lista_koniec, tab[0],tab[1],tab[2],tab[3],tab[4]);
			l=0; //resetujemy po 5 rekordach na 0 licznik
		}
		l++;								
	}
	ifile.close();
}

}

//=============================================================

//funkcja kasujaca baze w pamieci programu //int WyswietlKomunikat=0 //domyslnie nie wyswietlamy komunikatu void CBazaDanych::SkasujBaze(int WyswietlKomunikat) { if(this->lista_poczatek != NULL)//sprawdzamy czy lista nie jest pusta, bo jesli jest pusta to nie ma sensu tworzyc wskaznika { element* temp = this->lista_poczatek; int ID_delete; //id do skasowania while(temp != NULL) { ID_delete = temp->id; //przypisujemy do zmiennej pomocniczej ID poniewaz musimy przed usunieciem rekordu odczytac adres kolejnego elementu temp = temp->next; UsunRekord(0, ID_delete); //usuwamy rekord o danym ID } if(WyswietlKomunikat) { cout«“Usunieto wszystkie rekordy z pamieci programu!nn”; } } else if(WyswietlKomunikat) { cout«“Baza danych w pamieci programu jest pusta! Nie ma co tam kasowac!n”; }

if(WyswietlKomunikat) {
	cout<<"Czy chcesz rowniez aby wyczyscic plik txt bazy danych?n";
	ZapiszBazeDoPliku(0);//uruchamiamy tę metodę bez wyswietlania komunikatu z pytaniem czy chcemy skasowac baze txt
}

}

//=============================================================

void CBazaDanych::SortujRekordy() { CountLiczbaRekordow(); //przeliczamy liczbe rekordow

if(LiczbaRekordow) {

	cout<<"Wybierz kryterium wedlug ktorego posortowac baze:n"
		<<"1 - IDn"
		<<"2 - Imien"
		<<"3 - Nazwiskon"
		<<"4 - Rok studiown"
		<<"5 - Kieruneknn";
	char nawigacja;
	do {					
		nawigacja = _getch();
	} while(nawigacja != '1' && nawigacja != '2' && nawigacja != '3' && nawigacja != '4' && nawigacja != '5');				
	
	
	element* tab = new element[LiczbaRekordow];
	element* temp = this->lista_poczatek;

	//tworzymy tablice elementow
	int index=0;
	while(temp != NULL)
	{
		tab[index].id			=	temp->id;
		tab[index].imie			=	temp->imie;
		tab[index].nazwisko		=	temp->nazwisko;
		tab[index].rok_studiow	=	temp->rok_studiow;
		tab[index].kierunek		=	temp->kierunek;
		temp = temp->next;
		index++;
	}

	if(nawigacja == '1') {
		cout<<"Wybrales "ID" jako kryterium sortowania.nn";
		QuickSort(tab, 0, LiczbaRekordow-1, "id", 1);//przy pierwszym wywolaniu quicksort pytamy sie o kolejnosc w jakiej maja byc posortowane rekordy (typ sortowania: ASC lub DESC)
	} else if(nawigacja == '2') {
		cout<<"Wybrales "imie" jako kryterium sortowania.nn";
		QuickSort(tab, 0, LiczbaRekordow-1, "imie", 1);
	} else if(nawigacja == '3') {
		cout<<"Wybrales "nazwisko" jako kryterium sortowania.nn";
		QuickSort(tab, 0, LiczbaRekordow-1, "nazwisko", 1);
	} else if(nawigacja == '4') {
		cout<<"Wybrales "rok studiow" jako kryterium sortowania.nn";
		QuickSort(tab, 0, LiczbaRekordow-1, "rok_studiow", 1);
	} else if(nawigacja == '5') {
		cout<<"Wybrales  "kierunek" jako kryterium sortowania.nn";
		QuickSort(tab, 0, LiczbaRekordow-1, "kierunek", 1);
	}

	//wyswietlamy posortowane wyniki
	for(int i=0; i<LiczbaRekordow; i++) 
	{
		cout<<"ID:          "<<tab[i].id<<"n"
			<<"Imie:        "<<tab[i].imie<<"n"
			<<"Nazwisko:    "<<tab[i].nazwisko<<"n"
			<<"Rok studiow: "<<tab[i].rok_studiow<<"n"
			<<"Kierunek:    "<<tab[i].kierunek<<"n"
			<<"==========================================n";
	}

	cout<<"nCzy chcesz aby ta kolejnosc rekordow zostala zapamietana w pamieci programu?n"
		<<"1 - Tak (zapisz do pamieci programu ta kolejnosc rekordow)n"
		<<"2 - Nienn";
	do {					
		nawigacja = _getch();
	} while(nawigacja != '1' && nawigacja != '2');				
	if(nawigacja == '1') {		
		temp = this->lista_poczatek;
		index = 0;
		while(temp != NULL)
		{
			temp->id			=	tab[index].id;
			temp->imie			=	tab[index].imie;
			temp->nazwisko		=	tab[index].nazwisko;
			temp->rok_studiow	=	tab[index].rok_studiow;
			temp->kierunek		=	tab[index].kierunek;
			temp = temp->next;
			index++;
		}
		cout<<"Wyniki sortowania zostaly zapamietane w pamieci programu!n"
			<<"Jesli chcesz aby wyniki byly rowniez zapisane do bazy txt to skorzystaj z opcji nr 2";
	} else {
		cout<<"Wyniki sortowania NIE zostaly zapamietane w pamieci programu.";
	}
	delete [] tab;

} else {
	cout<<"Baza jest pusta, nie ma co sortowac!";
}

}

//=============================================================

void CBazaDanych::QuickSort(element t[], int p, int k, string co_sortowac, int kolejnosc) { static char typ_kolejnosci; if(kolejnosc) {//przy pierwszym uruchomieniu funkcji zapytamy o sposob prezentacji wynikow cout«“Wybierz sposob wyswietlenia posortowanych danych:n” «“1 - ASC (rekordy od najmniejszego do najwiekszego)n” «“2 - DESC (rekordy od najwiekszego do najmniejszego)nn”; do { typ_kolejnosci = _getch(); } while(typ_kolejnosci != ‘1’ && typ_kolejnosci != ‘2’);

}

int i, j, pivot;
string pivot_s; //pivot dla stringow
element wtemp;//pomocnicza zmienna
i = p; 
j = k;
if(co_sortowac == "id") {
	pivot = t[p].id; //definicja punkut podzialu
} else if(co_sortowac == "rok_studiow") {
	pivot = t[p].rok_studiow;
} else if(co_sortowac == "imie") {
	pivot_s = t[p].imie;
} else if(co_sortowac == "nazwisko") {
	pivot_s = t[p].nazwisko;
} else if(co_sortowac == "kierunek") {
	pivot_s = t[p].kierunek;
}
//cout<<"pivot = "<<pivot<<"n";
while(i < j) // moga sie minąć ale mogą też być równe (zamiana skrajnych)
{
	if(co_sortowac == "id") {
		if(typ_kolejnosci=='1') {
			while(t[i].id<pivot) i++;
			while(t[j].id>pivot) j--;
		} else {
			while(t[i].id>pivot) i++;
			while(t[j].id<pivot) j--;
		}
	} else if(co_sortowac == "rok_studiow") {
		if(typ_kolejnosci=='1') {
			while(t[i].rok_studiow<pivot) i++;
			while(t[j].rok_studiow>pivot) j--;
		} else {
			while(t[i].rok_studiow>pivot) i++;
			while(t[j].rok_studiow<pivot) j--;
		}
	} else if(co_sortowac == "imie") {
		if(typ_kolejnosci=='1') {
			while(t[i].imie<pivot_s) i++;
			while(t[j].imie>pivot_s) j--;
		} else {
			while(t[i].imie>pivot_s) i++;
			while(t[j].imie<pivot_s) j--;
		}
	} else if(co_sortowac == "nazwisko") {
		if(typ_kolejnosci=='1') {
			while(t[i].nazwisko<pivot_s) i++;
			while(t[j].nazwisko>pivot_s) j--;
		} else {
			while(t[i].nazwisko>pivot_s) i++;
			while(t[j].nazwisko<pivot_s) j--;
		}
	} else if(co_sortowac == "kierunek") {
		if(typ_kolejnosci=='1') {
			while(t[i].kierunek<pivot_s) i++;
			while(t[j].kierunek>pivot_s) j--;
		} else {
			while(t[i].kierunek>pivot_s) i++;
			while(t[j].kierunek<pivot_s) j--;
		}
	}

	if(i <= j)
	{
		//cout<<"zamiana: "<<t[i].id<<" z "<<t[j].id<<endl;
		wtemp = t[i];
		//zamieniamy tylko wartosci, a informacje o adresach do kolejnych elementow pozostaja bez zmian
		t[i].id = t[j].id;
		t[i].imie = t[j].imie;
		t[i].nazwisko = t[j].nazwisko;
		t[i].rok_studiow = t[j].rok_studiow;
		t[i].kierunek = t[j].kierunek;
		
		t[j].id = wtemp.id;
		t[j].imie = wtemp.imie;
		t[j].nazwisko = wtemp.nazwisko;
		t[j].rok_studiow = wtemp.rok_studiow;
		t[j].kierunek = wtemp.kierunek;
		
		i++;
		j--;
	}
}
if(i < k) {		
	QuickSort(t, i, k, co_sortowac, 0); //ostatnie 0 oznacza ze nie pytamy sie juz o tym sortowania: ASC lub DESC
	// od i tam gdzie sie zatrzymalo na i, az do k koniec tablicy
}
if(p < j) {		
	QuickSort(t, p, j, co_sortowac, 0);
}

}

//=============================================================

/* t - tekst ** w - wzorzec ** i - od ktorego znaku zaczynamy wyszukiwanie ** reset - jesli 1 to resetujemy zmienna statyczna przechowujaca informacje o tym czy w wyniku rekurencji udalo sie znalesc wzorzec ** jesli w tym samym programie bedziemy w roznych tekstach szukac roznych wzorcow to nalezy przed kazdym wywolaniem funkcji ustawic na 1 aby nastapila resetacja zmiennej statycznej, ktora jest pamietana z poprzedniego wyszukiwania wzorca! */ int CBazaDanych::StringFind(string t, string w, int i=0, int reset=1) { int x=0;//początkowy index dla wzorca int trash; //zmienna pomocnisza, poszczegolne wywolania funkcji zwracajace czy udalo sie dopasowac wzorzec beda do tej zmiennej przypisywane static int find = 0; if(reset) { find = 0; //jesli 1 to resetujemy zmienna statyczna }

if(i<t.length() && x<w.length()) {		
	if(t[i] == w[x]) {			
		int ok=1;
		for(int f=1; f<w.length(); f++) {
			if(t[i+f] == w[x+f]) {//sprawdzamy czy kolejne znaki sa rowne sobie po pierwszym wystapieniu literki a ze slowa ala
				ok++;
			} else {
				break; //jesli jakas literka sie nie zgadza to przerywamy petle bo wiemy juz ze wzorzec nie pasuje w calosci
			}
		}
		if(ok == w.length()) {//jesli liczba znalezionych literek jest rowna dlugosci wzorca to znaczy ze znalezlismy miejsce wystapienia wzorca
			find = 1;//ustawiamy ze dopasowalismy wzorzec
			int od_pozycji = i+1;
			int do_pozycji = i+w.length();
			/*cout<<"Dopasowano wzorzec od pozycji nr: "<<od_pozycji<<" do pozycji: "<<do_pozycji<<"n";
			cout<<t<<endl;
			for(int a=1; a<od_pozycji; a++) {
				cout<<" ";
			}
			cout<<w<<"nn";
			*/
			//po udanym dopasowaniu wzorca uruchamiamy funkcje by szukala kolejnego dopasowania w tekscie
			trash = StringFind(t, w, do_pozycji, 0);

		} else { //jesli nie uda sie dopasowac calego wzorca to szukamy od nastepnego znaku probujac znowu dopasowac caly wzorzec
			trash = StringFind(t, w, i+1, 0);
		}

	} else {			
		trash = StringFind(t, w, i+1, 0); //sprawdzamy kolejny znak czy jest rowny pierwszemu znakowi wzorca			
	}
}

return find;

}

//=============================================================

void CBazaDanych::WyszukajRekordy() { cout«“Wybierz kryterium wedlug ktorego chcesz przeszukac baze:n” «“1 - IDn” «“2 - Imien” «“3 - Naziwskon” «“4 - Rok studiown” «“5 - Kieruneknn”;

char nawigacja;
do {					
	nawigacja = _getch();
} while(nawigacja != '1' && nawigacja != '2' && nawigacja != '3' && nawigacja != '4' && nawigacja != '5');				

string wzorzec, kryterium;
int wzorzec_int;//uzywany w przypadku gdy wyszukujemy po ID
if(nawigacja == '1') {
	kryterium = "ID";
	cout<<"Podaj ID ktore chcesz znalesc: ";
	getline(cin,wzorzec);
	wzorzec_int = atoi(wzorzec.c_str()); //konwersja stringa na int
	while(wzorzec == "" || wzorzec_int == 0) {						
		if(wzorzec=="") {//podano pusty ciag znakow
			cout<<"Podales puste ID! Podaj poprawne ID: ";						
		} else { //podano ciag znakow o jakiejs dlugosci ktory zostal zamieniony na liczbe 0
			cout<<"Podales ciag znakow zamiast numeru! Podaj poprawne ID: ";
		}
		getline(cin,wzorzec);
		wzorzec_int = atoi(wzorzec.c_str());
	}

} else if(nawigacja == '2') {
	kryterium = "Imie";
	cout<<"Podaj imie ktore chcesz znalesc: ";
	getline(cin,wzorzec);
	while(wzorzec == "") {
		cout<<"Podales pusty ciag znakow! Podaj imie: ";
		getline(cin,wzorzec);
	}

} else if(nawigacja == '3') {
	kryterium = "Nazwisko";
	cout<<"Podaj nazwisko ktore chcesz znalesc: ";
	getline(cin,wzorzec);
	while(wzorzec == "") {
		cout<<"Podales pusty ciag znakow! Podaj nazwisko: ";
		getline(cin,wzorzec);
	}

} else if(nawigacja == '4') {
	kryterium = "Rok studiow";
	cout<<"Podaj rok studiow ktory chcesz znalesc: ";
	getline(cin,wzorzec);
	wzorzec_int = atoi(wzorzec.c_str()); //konwersja stringa na int
	while(wzorzec == "" || wzorzec_int == 0) {						
		if(wzorzec=="") {//podano pusty ciag znakow 
			cout<<"Podales pusty rok studiow! Podaj poprawny: ";						
		} else { //podano ciag znakow o jakiejs dlugosci ktory zostal zamieniony na liczbe 0
			cout<<"Podales ciag znakow zamiast roku studiow! Podaj poprawny: ";
		}
		getline(cin,wzorzec);
		wzorzec_int = atoi(wzorzec.c_str());
	}

} else if(nawigacja == '5') {
	kryterium = "Kierunek studiow";
	cout<<"Podaj kierunek ktory chcesz znalesc: ";
	getline(cin,wzorzec);
	while(wzorzec == "") {
		cout<<"Podales pusty ciag znakow! Podaj kierunek: ";
		getline(cin,wzorzec);
	}

}

cout<<"n";
//wyswietlamy rekordy pasujace do zapytania
if(this->lista_poczatek == NULL) {
	cout<<"Lista rekordow jest pusta! Nie ma w czym wyszukiwac!";

} else {
	
	//wyznaczanie obecnej daty
	//http://www.cplusplus.com/reference/clibrary/ctime/localtime/
	time_t rawtime;
	struct tm * timeinfo;
	time ( &rawtime );
	timeinfo = localtime ( &rawtime );
	string czas_teraz = asctime (timeinfo);

	string wyniki;
	wyniki+="=========================================================n";
	wyniki+="======  Kryterium: ""+kryterium+""n";
	wyniki+="=====  Wzorzec: ""+wzorzec+""n";
	wyniki+="====  Data: "+czas_teraz;
	wyniki+="===n";
	wyniki+="==  Znalezione rekordy ponizej: n";
	wyniki+="=nn";
	
			
	int rekordow=0;
	int pasuje; //informacja czy rekord pasuje do wzorca
	string temps;
	element* temp = this->lista_poczatek;
	while(temp != NULL)
	{	
		pasuje = 0;//zakladamy ze rekord nie pasuje do wzorca
		switch(nawigacja)
		{
		case '1'://czy ID rowne wzorzec_int
			if(temp->id == wzorzec_int) pasuje=1;
			break;
		case '2':
			pasuje = StringFind(temp->imie, wzorzec); //zwraca 1 jesli wzorzec pasuje do tekstu
			break;
		case '3':
			pasuje = StringFind(temp->nazwisko, wzorzec); 
			break;
		case '4':
			if(temp->rok_studiow == wzorzec_int) pasuje=1;
			break;
		case '5':
			pasuje = StringFind(temp->kierunek, wzorzec); 
			break;
		}

		if(pasuje) //jesli rekord pasuje to zapisujemy go do wynikow
		{
			temps = IntToString(temp->id);
			wyniki+="ID:          "+temps+"n";
			wyniki+="Imie:        "+temp->imie+"n";
			wyniki+="Nazwisko:    "+temp->nazwisko+"n";
			temps = IntToString(temp->rok_studiow);
			wyniki+="Rok studiow: "+temps+"n";
			wyniki+="Kierunek:    "+temp->kierunek+"n";
			wyniki+="==========================================n";
			rekordow++;
		}

		temp = temp->next;
		
	}
			
	temps = IntToString(rekordow);
	wyniki+="n=n";
	wyniki+="==n";
	wyniki+="===  Rekordow pasujacych do wzorca: "+temps+"n";
	wyniki+="=========================================================nnn";
	

	if(rekordow) {//jesli znaleziono jakies rekordy to je wyswietl + zapytanie czy dopisac do loga

		cout<<wyniki;

		cout<<"Czy chcesz zapisac wyniki wyszukiwania w pliku?n"
			<<"1 - Tak, dopisz wyniki do pliku log_wyszukiwanie.txtn"
			<<"2 - Nie zapisujnn";
		char nawigacja2;
		do {					
			nawigacja2 = _getch();
		} while(nawigacja2 != '1' && nawigacja2 != '2');				
		if(nawigacja2 == '1') {
			cout<<"Wyniki zostaly dopisane do pliku log_wyszukiwanie.txt!";
			fstream plik;
			plik.open(this->URL_LogWyszukiwanie, ios::app); //ustawiamy tryb dopisywania do pliku
			plik<<wyniki;
			plik.close();
		} else {
			cout<<"Wyniki NIE zostaly zapisane!";
		}
	
	} else {
		cout<<"Nie znaleziono rekordow ktore pasowalyby do podanego wzorca: ""<<wzorzec<<""n"
			<<"dla zadanego kryterium: ""<<kryterium<<""!";
	}


}

}

//=============================================================

//konwersja int na string string CBazaDanych::IntToString(int number) { stringstream ss; ss « number; return ss.str(); }

//============================================================= [/code]

W katalogu projektu należy umieścić folder: “baza_log”, a w nim 3 pliki: a) [u]AutoIncrement.txt[/u] Do tego pliku zapisywany jest ostatnio przydzielony ID rekordu. b) [u]log_wyszukiwanie.txt[/u] W tym pliku zapisywane są wyniki wyszukiwania przeprowadzone na bazie danych. c) [u]BazaStudentow.txt[/u] Plik bazy danych. Poniżej podaje kilka przykładowych rekordów. [b]Uwaga![/b] Ostatnia liniia pliku musi być pusta. Plik zawiera zmyślone nazwiska. [code=plain] 1 artur nowak 1 informatyka 2 adrian kowalski 2 filozofia 3 michal wielki 2 matematyka 4 franciszek bokser 6 geodezja 5 kamil kowalski 3 psychologia 6 wojciech krol 6 elektrotechnika 7 marcin wrobel 1 psychologia 8 tomasz tomaszewski 7 matematyka 9 anna kowalska 1 elektrotechnika 10 bartlomiej nowak 6 informatyka

[/code]