
#include <iostream>
#include <fstream>
#include <iomanip>

using namespace std;


struct student
{
	char ime[20];
	char prezime[20];
	char sifra[8];
};


void UpisiSortiranNiz(char *Datoteka,student *s, int Broj)
{

	ofstream f(Datoteka, ios::app);

	f << "-----------------------------------------------------------" << '\n';
	for(int i=0; !(!f) && i<Broj;i++)
		f << s[i].ime << ' ' << s[i].prezime << ' ' << s[i].sifra << '\n';
	
	if(!f)	
	{
		f.close();
		throw "Podaci se ne mogu upisati";
	}
	else
		f.close();	
}


void Citanje(char *Datoteka, student *s, int Broj)
{
	ifstream f(Datoteka);
	
	for(int i=0; !(!f) && i<Broj;i++)
		f >> s[i].ime >> s[i].prezime >> s[i].sifra;
	
	if(!f)	
	{
		f.close();
		throw "Neispravna datoteka, ne mogu se ucitati podaci";
	}
	else
		f.close();	

}


int OdrediBrojRedova(char *Datoteka)
{
	char c;
	int BrojRedova = 0;
	ifstream f(Datoteka);

	while(1)
	{
		c = f.get();
		if (!f) 
			break;
		if(c == '\n') 
			BrojRedova++;
	}

	f.close();

	return BrojRedova;
}



int compare( const void *arg1, const void *arg2 )
{
 
	int r = strcmp( ((student*)arg1)->prezime, ((student*)arg2)->prezime);
	if (r) 
		return r;

    r = strcmp( ((student*)arg1)->ime, ((student*)arg2)->ime );
	if (r) 
		return r;

	r = strcmp( ((student*)arg1)->sifra, ((student*)arg2)->sifra);
	if (r) 
		return r;
	
	throw "Neispravni ulazni podaci: dva studenta sa istim podacima!";

}




main()
{

	student *s;	
	char UlaznaDatoteka[50];
	char IzlaznaDatoteka[50];

	cout << "Unesi ime ulazne datoteke" << endl;
	cin >> setw(sizeof(UlaznaDatoteka))  >> UlaznaDatoteka;

	cout << "Unesi ime izlazne datoteke" << endl;
	cin >> setw(sizeof(IzlaznaDatoteka)) >> IzlaznaDatoteka;

	try
	{
	int Broj = OdrediBrojRedova(UlaznaDatoteka);

	if (!Broj) throw Broj;
	
	s = new student[Broj];

	Citanje(UlaznaDatoteka, s, Broj);
	
    qsort( (void *)s, Broj, sizeof(student), &compare );

	UpisiSortiranNiz(IzlaznaDatoteka,s,Broj);

	delete s;

	}

	catch(int){
	cout<< "greska: u datoteci nema studenata!" << endl;
	}

	catch(char* str){
	cout<< "greska:" << str << endl;
	delete s;
	}

	catch(...) {
	cout<< "Nepoznata greska!" << endl;
	}

	return 0;
}
