// Maciej Stefańczyk
// gr. J1I2

#include <string>
#include <iostream>

using namespace std;

// wypisanie informacji o podanym napisie
void info(const string & str, const string & desc) {
	cout << desc << endl;
	cout << "\"" << str << "\"\n";

	// długość napisu (ilość znaków)
	cout << "length:   " << str.length() << endl;
	// ilość znaków, które może pomieścić napis bez alokacji dodatkowej pamięci
	// po jej przekroczeniu automatycznie alokowana jest nowa pamięć
	// o wielkości dwukrotnie większe niż dotychczasowa
	cout << "capacity: " << str.capacity() << endl;
	cout << endl;
}

int main() {
	{
		// napis "123456789"
		string s1("123456789");

		// prosty sposób na odwrócenie kolejności znaków w napisie
		// wykorzystujemy konstruktor przyjmujący jako parametry dwa iteratory
		// napis powstaje przez skopiowanie znaków począwszy od rbegin
		// (czyli od ostatniego znaku) aż do znaku poprzedzającego rend
		// (czyli do pierwszego znaku)
		string s2(s1.rbegin(), s1.rend());

		cout << "s1: \"" << s1 << "\"\n";
		cout << "s2: \"" << s2 << "\"\n\n";
	}

	{
		// utowrzenie napisu składającego się z 10 znaków x
		string s(13, 'x');
		info(s, "string(13, 'x')");
		cout << "Maksymalna dozwolona długość napisu: " << s.max_size() << " znaków\n";

		// dopisanie na końcu napisu
		s+="yy";
		info(s, "s+=\"yy\"");

		// zarezerwowanie dodatkowego miejsca w pamięci dla napisu
		// przy częstych operacjach na napisach umożliwia zredukowanie ilości
		// automatycznych operacji wydłużania napisu podczas dopisywania nowych danych
		// UWAGA: zarezerwowane może być więcej miejsca niż wymagamy
		s.reserve(50);
		info(s, "s.reserve(50)");

		// jeśli chcemy zmniejszyć ilość miejsca zajmowanego przez napis w pamięci
		// do minimum, możemy wymusić rezerwację zerowej ilości pamięci
		s.reserve(0);
		info(s, "s.reserve(0)");

		// jeśli chcemy zmienić długość napisu, nalezy użyć funkcji resize
		// wydłużenie napisu do 20 znaków, jako nowe znaki dodane zostaną myślniki
		s.resize(20, '-');
		info(s, "s.resize(20, '-')");

		// skrócenie napisu
		s.resize(5);
		info(s, "s.resize(5)");

		// sprawdzenie, czy napis jest pusty
		if (!s.empty()) {
			// wyczyszczenie zawartości napisu
			s.clear();
			info(s, "s.clear()");
		}

	}

	{
		string s;
		string k = "kotara";
		size_t found;

		// przypisanie nowej zawartości do napisu
		s = "J+a+n ma 123\t lata. 123";

		cout << "\"" << s << "\"\n";

		// wyszukujemy pierwsze wystapienie podanego ciągu w napisie
		// jeśli zostanie znalezione
		// zamieniamy w napisie 3 znaki począwszy od pozycji, na której
		// zaczyna się znaleziony ciąg na nowy pierwsze dwa znaki podanego ciągu
		while ( (found = s.find("123")) != string::npos )
			s.replace(found, 3, "42086", 2);

		// wyszukujemy dowolny z podanych znaków a nastepnie usuwamy go z napis
		while ( (found = s.find_first_of("+-\t")) != string::npos )
			s.erase(found, 1);

		// wyszukujemy każde wystąpienie ciągu 'Jan' a nastepnie wstawiamy za nim
		// dodatkowy ciąg znaków
		// wyszukiwanie za każdym razem zaczynamy od miejsca, w którym wstawiliśmy nowy ciąg
		found = 0;
		while ( (found = s.find("Jan", found)) != string::npos ) {
			s.insert(found+3, "usz");
			found += 3;
		}

		// skracamy napis do miejsca, gdzie występuje ostatni znak przestankowy
		found = s.find_last_of(".,;");
		if (found != string::npos)
			s.resize(found+1);

		// dodajemy na końcu spację
		s += ' ';

		// dodajemy na końcu napisu fragment składający się z części aktualnego napisu
		// zaczynającej się na pierwszym znaku i zawierającej 10 znaków
		s.append(s.substr(0, 10));

		// zamieniamy ostatnie słowo Janusz na Ala
		found = s.rfind("Janusz");
		if (found != string::npos)
			s.replace(found, 6, "Ala");

		// dodajemy na końcu pierwsze 5 znaków z napisu k
		s.append(k, 0, 5);

		// zamieniamy ostatni znak na kropkę
		s[s.size()-1] = '.';

		cout << "\"" << s << "\"\n\n";
	}

	{
		string str1 ("malutkie drzewo");
		string str2 ("ogromne drzewo");

		// porównanie dwóch napisów w całości
		if (str1.compare(str2) != 0)
			cout << str1 << " to nie " << str2 << "\n";

		// porównanie części pierwszego napisu z podanym wzorcem
		// porównywane jest 6 znaków począwszy od znaku na pozycji 9
		if (str1.compare(9, 6, "drzewo") == 0)
			cout << str1 << " to drzewo\n";

		// w ten sposób porównujemy 6 ostatnich znaków z wzorcem
		if (str2.compare(str2.size()-6, 6, "drzewo") == 0)
			cout << "oraz " << str2 << " to też drzewo\n";

		// porównanie części napisu 1 z częścią napisu 2
		// pierwsze dwie cyfry odnoszą się do napisu 1
		// ostatnie dwie cyfry oznaczają pozycję i długość podciągu z drugiego napisu
		if (str1.compare(9, 6, str2, 8, 6) == 0)
			cout << "więc mamy dwa drzewa\n\n";
	}


	return 0;
}
