// Zliczanie i sortowanie słów ze standardowego wejścia.

#include <iostream>
#include <string>

// po to, zebysmy nie musieli pisac std.cout, a tylko cout
using namespace std;

// strukturka z wyrazami
struct word {
	char *str;
};

// klasa Words
class Words
{
public:
	Words(); 		// konstruktor
	~Words(); 		// destruktor
	void add(char *slowo);	// dodaje slowo
	void sort();		// sortuj slowa
	void print();		// drukuj slowa
protected:
	int count;		// ilosc slow
	struct word **wordarray;// tablica slow
};

// konstruktor klasy Words
Words::Words()
{
	count = 0;
	wordarray = NULL;
}

// destruktor klasy Words
Words::~Words()
{
	delete [] wordarray;	// usunmy allocowana pamiec
	count = 0;
}

// funkcja porownujaca dwa wyrazy, na potrzeby qsort()
int compare(const void *a, const void *b) {
	struct word * const *one = (struct word* const*)a;
	struct word * const *two = (struct word* const*)b;

	return strcmp((*one)->str, (*two)->str);
}

// sortuj wyrazy za pomoca funkcji qsort()
void Words::sort()
{
	qsort(wordarray, count, sizeof(*wordarray), compare);
}

// dodaj wyraz 
void Words::add(char *slowo)
{
	// poszerzmy nasza tablice slow
  	wordarray = (struct word **)realloc(wordarray, (count+1)*sizeof(struct word *));
	// zaallokujmy pamiec dla nastepnego wskaznika
	wordarray[count] = new struct word;
	// skopiujmy wyraz 
	wordarray[count]->str = strdup(slowo);
	// i zwiekszmy licznik wyrazow o jeden
	count++;
}

// wydrukuj na ekran wszystkie slowa
void Words::print()
{
	int i;
	
	for (i = 0; i < count; i++) {
		cout << wordarray[i]->str << endl;
	}
}

// funkcja glowna
int main(int arch, char **argv)
{
	char line[256];
	Words *words = new Words();

	cout << "Wczytuje wyrazy ze standardowego wejscia..." << endl;
	while (cin >> line)
		words->add(line);
	
	cout << "Wyrazy przed sortowaniem:" << endl;
	words->print();

	words->sort();

	cout << "Wyrazy po sortowaniu:" << endl;
	words->print();

	delete words;

	return 0;
}

