You are on page 1of 15

C++ rad sa datotekama i sortiranje

1. Zadatak
Neka je data datoteka sa izgledom sloga:
struct korisnik {
int id;
char Ime[20];
char Prezime[20];
char Br_tel[20];
};
I neka je napunjena datoteka imenik.dat sa korisnicima koji nisu sortirani. Napisati
program koji e napraviti novu tekstualnu datoteku imenik.txt sa sortiranim korisnicima.
(Zadatak rijeiti prvo koritenjem bubble sorta, a zatim quick sorta.)

2. Zadatak
Implementirati dvostruku spregnutu listu sa izgledom vora:
struct cvor {
int id;
char Ime[20];
char Prezime[20];
char Br_tel[20];
cvor *sljedeci;
cvor *prethodni;
}
koja e moi uitati iz datoteke imenik.dat lanove imenika u listu. Omoguiti operacije
dodavanja novog vora na poetak, na kraj, na poziciju, brisanje vorova, ispis liste,
pretraivanje liste, te ponovno snimanje promjenjene liste u datoteku imenik.dat.

Napomena: Svi zadaci su rjeeni i testirani sa Dev-C++ IDE v.4.9.9.2 i Borland C++ 5.5
Command Line Tools paralelno

1. Zadatak rjeenje
// teststruct.cpp kreira i puni datoteku imenik1.dat sa nesortiranim zapisima
#include <iostream>
#include <fstream>
using namespace std;
int filesize();
struct teststruct
{
int id;
char Ime[20];
char Prezime[20];
char Br_tel[20];
};
#define VELICINA_STRUKTURE 64
main() {
///////// upis strukture u fajl //////////
teststruct ts[] = {
6, "Smajos", "Ibrahimos", "068-111-111",
5, "Igoros", "Prses", "069-222-333",
4, "Edhemaga", "Burzukos", "067-444-555",
3, "Ilijus", "Mrvikos", "067-999-888",
2, "Ilkos", "Marelikoz", "067-777-797",
1, "Ilkos", "Marelikos", "069-756-981" };
ofstream of("imenik1.dat");
of.write((char *)(&ts),sizeof(ts));
of.close();
//////// citanje strukture iz fajla ////////
int i;
int n = filesize()/VELICINA_STRUKTURE;
ifstream in("imenik1.dat");
i=0;
while (i<n) {
in.read((char *)(&ts[i]), sizeof(ts));
i++;
}
in.close();
////// kontrolni ispis na ekran ///////////
cout << "Struktura ima " << n << " zapisa:" << endl << endl;
i=0;
while (i<n) {
cout << ts[i].id << endl;
cout << ts[i].Ime << endl;
cout << ts[i].Prezime << endl;
cout << ts[i].Br_tel << endl << endl;
i++;
}
///////////////////////////////////////
1

cout << endl;


system("pause");
} // end of main
//////////////////////////////////////////////////////////////////////////////
int filesize(){
ifstream in;
in.open ("imenik1.dat", ios::binary );
if (in.good()==false) {cout << "Datoteka se ne moze otvoriti!\n";}
in.seekg (0, ios::end);
int bajtova = in.tellg();
in.close ();
if (in.good()==false) {cout << "Datoteka se ne moze zatvoriti!\n";}
return bajtova;
}
//////////////////////////////////////////////////////////////////////////////

1. Zadatak a) rjeenje bubble sortom


/* bsortimenik.cpp radi "bubble-sort" algoritam nad datotekom
imenik1.dat i sprema sortiranu strukturu po prezimenu u imenik1.txt */
#include <iostream>
#include <fstream>
using namespace std;
struct korisnik
{
int id;
char Ime[20];
char Prezime[20];
char Br_tel[20];
};
#define VELICINA_STRUKTURE 64
int filesize();
void zamjeni(korisnik& x, korisnik& y);
void bsort(korisnik niz[], int duzinaNiza);

main() {
int i;
int n = filesize() / VELICINA_STRUKTURE;
korisnik *ts = new korisnik[n];
////// citanje strukture iz fajla ////////////////////////////////
ifstream in("imenik1.dat");
i=0;
while (i<n) {
in.read((char *)(&ts[i]), sizeof(ts[n]));
i++;
2

}
in.close();
////// kontrolni ispis na ekran /////////////////////////////////
cout << "Datoteka 'imenik1.dat' sadrzi " << n << " zapisa:" << endl << endl;
i=0;
while (i<n) {
cout << ts[i].id << endl;
cout << ts[i].Ime << endl;
cout << ts[i].Prezime << endl;
cout << ts[i].Br_tel << endl << endl;
i++;
}
/////// sortiranje po prezimenu i ponovni ispis /////////////////
bsort(ts, n);
cout << endl << "Izgled zapisa nakon sortiranja po prezimenu: " << endl << endl;
for (int i=0; i<n; i++) {
cout << ts[i].Prezime << endl;
cout << ts[i].Ime << endl;
cout << ts[i].id << endl;
cout << ts[i].Br_tel << endl << endl;
}
//////// spremanje u datoteku 'imenik1.txt' ///////////////////
ofstream out;
out.open("imenik1.txt");
if (out.good()==false) {cout << "GRESKA: Datoteka se ne moze otvoriti!\n";}
i=0;
while (i<n) {
out.write((char *)(&ts[i]), sizeof(ts[n]));
i++;
}
out.close();
if (out.good()==false) {cout << "GRESKA: Datoteka se ne moze zatvoriti!\n";}
////// kraj programa //////////////////////////////////////
cout << endl;
system("pause");
}
//////////////////////////////////////////////////////////////////////////////
// odredjivanje velicine fajla
int filesize(){
ifstream in;
in.open ("imenik1.dat", ios::binary );
if (in.good()==false) {cout << "GRESKA: Datoteka se ne moze otvoriti!\n";}
in.seekg (0, ios::end);
int bajtova = in.tellg();
in.close ();
if (in.good()==false) {cout << "GRESKA: Datoteka se ne moze zatvoriti!\n";}
return bajtova;
}
3

//////////////////////////////////////////////////////////////////////////////
// zamjena elemenata
void zamjeni(korisnik& x, korisnik& y) {
korisnik z = x;
x = y;
y = z;
}
//////////////////////////////////////////////////////////////////////////////
// bubble-sort po prezimenu
void bsort(korisnik niz[], int duzinaNiza) {
int i, j, k;
for (i=duzinaNiza-1; i>0; i--) {
for (j=0; j<i; j++) {
k=0;
while (niz[j].Prezime[k] == niz[j+1].Prezime[k]) {
k++;}
if (niz[j].Prezime[k] > niz[j+1].Prezime[k]) {zamjeni(niz[j], niz[j+1]);}
}
}
}
//////////////////////////////////////////////////////////////////////////////

1. Zadatak b) rjeenje quick sortom


/* qsortimenik.cpp radi "quick-sort" algoritam nad datotekom
imenik1.dat i sprema sortirane strukture po id u imenik1.txt */
#include <iostream>
#include <fstream>
using namespace std;
struct korisnik
{
int id;
char Ime[20];
char Prezime[20];
char Br_tel[20];
};
int filesize();
void zamjeni(korisnik& x, korisnik& y);
int podjeli (korisnik niz[], int n);
void qsort(korisnik niz[], int n);
#define VELICINA_STRUKTURE 64

main() {
int i;
int n = filesize() / VELICINA_STRUKTURE;

korisnik *ts = new korisnik[n];


////// citanje strukture iz fajla /////////////////////////////////////////////
ifstream in("imenik1.dat");
i=0;
while (i<n) {
in.read((char *)(&ts[i]), sizeof(ts[n]));
i++;
}
in.close();
////// kontrolni ispis na ekran ///////////////////////////////////////////////
cout << "Datoteka 'imenik1.dat' sadrzi " << n << " zapisa:" << endl << endl;
i=0;
while (i<n) {
cout << ts[i].id << endl;
cout << ts[i].Ime << endl;
cout << ts[i].Prezime << endl;
cout << ts[i].Br_tel << endl << endl;
i++;
}
/////// sortiranje po id i ponovni ispis //////////////////////////////////////
qsort(ts, n);
cout << endl << "Izgled zapisa nakon sortiranja po id: " << endl << endl;
for (int i=0; i<n; i++) {
cout << ts[i].Prezime << endl;
cout << ts[i].Ime << endl;
cout << ts[i].id << endl;
cout << ts[i].Br_tel << endl << endl;
}
//////// spremanje u datoteku 'imenik1.txt' /////////////////////////////////////
ofstream out;
out.open("imenik1.txt");
if (out.good()==false) {cout << "GRESKA: Datoteka se ne moze otvoriti!\n";}
i=0;
while (i<n) {
out.write((char *)(&ts[i]), sizeof(ts[n]));
i++;
}
out.close();
if (out.good()==false) {cout << "GRESKA: Datoteka se ne moze zatvoriti!\n";}
////// kraj programa ///////////////////////////////////////////////////////////
cout << endl;
system("pause");
}
//////////////////////////////////////////////////////////////////////////////
// odredjivanje velicine fajla
int filesize(){
ifstream in;
5

in.open ("imenik1.dat", ios::binary );


if (in.good()==false) {cout << "GRESKA: Datoteka se ne moze otvoriti!\n";}
in.seekg (0, ios::end);
int bajtova = in.tellg();
in.close ();
if (in.good()==false) {cout << "GRESKA: Datoteka se ne moze zatvoriti!\n";}
return bajtova;
}
//////////////////////////////////////////////////////////////////////////////
// zamjena elemenata strukture
void zamjeni(korisnik& x, korisnik& y) {
korisnik z = x;
x = y;
y = z;
}
//////////////////////////////////////////////////////////////////////////////
/* funkcija podjeli razbija niz struktura od n elemenata na dvije
particije i vraca index elementa koji djeli niz struktura na particije */
int podjeli (korisnik niz[], int n) {
int i=0, j=n-1;
int b = niz[n-1].id;
while (i<j) {
while (niz[i].id < b && i<=n-1) i++;
while (niz[j].id >= b && j>=0) j--;
if (i<j) zamjeni (niz[i], niz[j]);
}
zamjeni (niz[i], niz[n-1]);
return i;
}
//////////////////////////////////////////////////////////////////////////////
/* funkcija qsort sortira niz struktura od n elemenata tako sto ga prvo podjeli
na dvije particije, a zatim sortira dobijene particije rekurzivnim pozivima */
void qsort (korisnik niz[], int n) {
if (n>1) {
int i = podjeli(niz, n);
qsort(niz, i);
qsort(niz+i+1, n-i-1);
}
}
//////////////////////////////////////////////////////////////////////////////

2. Zadatak - rjeenje
// imeniklista.cpp radi sa datotekom imenik2.dat u istom direktoriju
#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstring>
using namespace std;
struct Cvor{
int id;
char Ime[20];
char Prezime[20];
char Br_tel[20];
Cvor *prethodni;
Cvor *sljedeci;
};
Cvor *glava = NULL;
Cvor *rep = NULL;
char odgovor[19];
Cvor *initCvor();
void dodajNaKraj(Cvor *noviCvor);
void dodajNaPocetak(Cvor *noviCvor);
void dodajNaPoziciju(int poz, Cvor *noviCvor);
void obrisiSaPozicije(int poz);
void ispisiSaPozicije(int poz);
void ispisi();
void ispisiUnazad();
int velicina();
void izbrisiImenik();
void ucitajImenikC();
void snimiImenikC();
void ucitajImenik();
void snimiImenik();
int filesize();
void traziPrezimeC();

main() {
ucitajImenikC();
//ucitajImenik(); radi OK cpp verzija
int poz;
char opcija[4];
for (;;) {
cout<<endl<<"1. Unos novog korisnika na kraj imenika"<<endl;
cout<<"2. Unos novog korisnika na pocetak imenika"<<endl;
cout<<"3. Unos novog korisnika na poziciju u imeniku"<<endl;
cout<<"4. Brisanje korisnika sa pozicije u imeniku"<<endl;
cout<<"5. Brisanje svih korisnika iz imenika"<<endl;
cout<<"6. Ispis korisnika s pozicije u imeniku"<<endl;
cout<<"7. Ispis svih korisnika iz imenika"<<endl;
cout<<"8. Snimi imenik u datoteku"<<endl;
7

cout<<"9. Pretrazi imenik po prezimenu"<<endl;


cout<<"0. Izlaz iz programa"<<endl;
cout<<endl<<"Izaberite opciju: ";
cin>>opcija;
int meni = atoi(opcija);
switch(meni) {
case 1:
dodajNaKraj(initCvor());
break;
case 2:
dodajNaPocetak(initCvor());
break;
case 3:
cout<<"Unesite poziciju za novog korisnika: ";
cin>>poz;
dodajNaPoziciju(poz, initCvor());
break;
case 4:
cout<<"Unesite poziciju korisnika za brisanje: ";
cin>>poz;
obrisiSaPozicije(poz);
break;
case 5:
izbrisiImenik();
break;
case 6:
cout<<"Unesite poziciju korisnika za ispis: ";
cin>>poz;
ispisiSaPozicije(poz);
break;
case 7:
cout<<"Bilo sta za ispis unaprijed"<<endl;
cout<<"Broj 2 za ispis unazad"<<endl;
cout<<"Izaberite nacin ispisa: ";
cin>>opcija;
meni = atoi(opcija);
if (meni==2) ispisiUnazad();
else ispisi();
break;
case 8:
snimiImenikC();
//snimiImenik(); radi OK cpp verzija
break;
case 9:
traziPrezimeC();
break;
case 0: exit(0);
default: exit(0);
}
}
}
//////////////////////////////////////////////////////////////////////////////
Cvor *initCvor() {
8

Cvor *pokCvor = new Cvor();


int br;
if(pokCvor == NULL) {
cout<<"Greska u memoriji."<<endl;
return NULL;
}
else {
cout<<"Unesite id: ";
cin>>br;
pokCvor->id = br;
cout<<"Unesite ime: ";
cin>>odgovor;
strcpy(pokCvor->Ime, odgovor);
cout<<"Unesite prezime: ";
cin>>odgovor;
strcpy(pokCvor->Prezime, odgovor);
cout<<"Unesite broj telefona: ";
cin>>odgovor;
strcpy(pokCvor->Br_tel, odgovor);
pokCvor->sljedeci = NULL;
pokCvor->prethodni = NULL;
return pokCvor;
}
}
//////////////////////////////////////////////////////////////////////////////
void dodajNaPocetak(Cvor *noviCvor){
if(glava == NULL) {
glava = noviCvor;
rep = noviCvor;
}
else {
glava->prethodni=noviCvor;
noviCvor->prethodni = NULL;
noviCvor->sljedeci = glava;
glava = noviCvor;
}
}
//////////////////////////////////////////////////////////////////////////////
void dodajNaKraj(Cvor *noviCvor) {
if(glava == NULL) {
glava = noviCvor;
rep = noviCvor;
}
else {
noviCvor->sljedeci = NULL;
noviCvor->prethodni = rep;
rep->sljedeci = noviCvor;
rep = noviCvor;
}
}
//////////////////////////////////////////////////////////////////////////////

void ispisi() {
Cvor *tmpCvor = glava;
while(tmpCvor != NULL) {
cout<<tmpCvor->id<<endl;
cout<<tmpCvor->Ime<<endl;
cout<<tmpCvor->Prezime<<endl;
cout<<tmpCvor->Br_tel<<endl<<endl;
tmpCvor = tmpCvor->sljedeci;
}
}
//////////////////////////////////////////////////////////////////////////////
void ispisiUnazad() {
Cvor *tmpCvor = rep;
while(tmpCvor != NULL) {
cout<<tmpCvor->id<<endl;
cout<<tmpCvor->Ime<<endl;
cout<<tmpCvor->Prezime<<endl;
cout<<tmpCvor->Br_tel<<endl<<endl;
tmpCvor = tmpCvor->prethodni;
}
}
//////////////////////////////////////////////////////////////////////////////
int velicina() {
int brojac = 0;
Cvor *tmpCvor;
tmpCvor = glava;
while(tmpCvor != NULL) {
brojac++;
tmpCvor = tmpCvor->sljedeci;
}
return brojac;
}
//////////////////////////////////////////////////////////////////////////////
void izbrisiImenik() {
Cvor *tmpCvor;
Cvor *brisaniCvor;
tmpCvor = glava;
while(tmpCvor != NULL) {
brisaniCvor = tmpCvor;
tmpCvor = tmpCvor->sljedeci;
delete brisaniCvor;
}
glava = NULL;
rep = NULL;
}
//////////////////////////////////////////////////////////////////////////////
void ispisiSaPozicije(int poz) {
if(poz < 1 || poz > velicina()) {
cout<<"NEPRAVILNO UNESENA POZICIJA!!!"<<endl;
}
10

else {
Cvor *zaIspis=glava;
for(int i=0; i<poz-1; i++) {
zaIspis=zaIspis->sljedeci;
}
cout<<"Cvor sa pozicije br."<<poz<<" je: "<<zaIspis->id<<endl;
}
}
//////////////////////////////////////////////////////////////////////////////
void dodajNaPoziciju (int poz, Cvor *noviCvor) {
Cvor *prethodni;
Cvor *sljedeci;
if(poz < 1 || poz > velicina()+1) {
cout<<"NEPRAVILNO UNESENA POZICIJA!!!"<<endl;
delete noviCvor;
}
else {
if (poz==1) {
dodajNaPocetak(noviCvor);
}
else if (poz==velicina()+1) {
dodajNaKraj(noviCvor);
}
else {
prethodni = glava;
for(int i=0; i<poz-2; i++) {
prethodni=prethodni->sljedeci;
}
noviCvor->sljedeci=prethodni->sljedeci;
prethodni->sljedeci=noviCvor;
noviCvor->prethodni=prethodni;
sljedeci=noviCvor->sljedeci;
sljedeci->prethodni=noviCvor;
}
}
}
//////////////////////////////////////////////////////////////////////////////
void obrisiSaPozicije(int poz) {
Cvor *prethodni;
Cvor *sljedeci;
if (poz<1 || poz>velicina()) { // provjera vrijednosti unesene pozicije
cout<<"NEISPRAVNO UNESENA POZICIJA!!!"<<endl;
}
else {
if (poz==1) { // brisanje cvora ako je na 1. mjestu
Cvor *tmpCvor=glava;
glava=tmpCvor->sljedeci;
glava->prethodni=NULL;
delete tmpCvor;
}
else if (poz==velicina()) { // ako je na zadnjem mjestu
Cvor *tmpCvor=rep;
11

rep=tmpCvor->prethodni;
rep->sljedeci=NULL;
delete tmpCvor;
}
else { // ako je negdje u sredini liste
prethodni=glava;
for (int i=0; i<poz-2; i++) {
prethodni=prethodni->sljedeci;
}
Cvor *tmpCvor=prethodni->sljedeci;
sljedeci=tmpCvor->sljedeci;
prethodni->sljedeci=tmpCvor->sljedeci;
sljedeci->prethodni=prethodni;
delete tmpCvor;
}
}
}
//////////////////////////////////////////////////////////////////////////////
void snimiImenikC() {
struct Cvor *tC;
FILE *fp;
fp = fopen("imenik2.dat", "wb");
if (!fp) {
printf("GRESKA: Datoteka se ne moze otvoriti!\n");
return;
}
printf("\nSnimanje...\n");
tC = glava;
while(tC) {
fwrite(tC, sizeof(struct Cvor), 1, fp);
tC = tC->sljedeci;
}
fclose(fp);
}
//////////////////////////////////////////////////////////////////////////////
void ucitajImenikC() {
Cvor *tC;
FILE *fp;
int i=0;
fp = fopen("imenik2.dat", "rb");
if(!fp) {
printf("GRESKA: Datoteka se ne moze otvoriti ili nije jos kreirana!\n");
printf("Imenik radi sa datotekom 'imenik2.dat' u istom direktoriju.\n");
printf("Program sam kreira datoteku pri prvom snimanju imenika.\n");
return;
}
while(!feof(fp)) {
tC = (struct Cvor *) malloc(sizeof(struct Cvor));
if (!tC) { printf("Nema memorije"); return; }
if (1 != fread(tC, sizeof(struct Cvor), 1, fp)) { break; }
dodajNaKraj(tC);
i++;
12

}
printf("Ucitano je %d", i);
printf(" zapisa iz imenika.\n");
fclose(fp);
}
//////////////////////////////////////////////////////////////////////////////
void snimiImenik() {
Cvor *ts;
ts = glava;
ofstream out;
out.open("imenik2.dat");
if (out.good()==false) {cout << "GRESKA: Datoteka se ne moze otvoriti!\n";}
while (ts) {
out.write((char *)(ts), sizeof(Cvor));
ts = ts->sljedeci;
}
out.close();
}
//////////////////////////////////////////////////////////////////////////////
void ucitajImenik() {
int m = filesize();
if (m!=0)
{
int n = filesize() / sizeof(Cvor);
ifstream in("imenik2.dat");
int i=0;
while (i<n) {
Cvor *ts = new Cvor();
in.read((char *)(ts), sizeof(Cvor));
dodajNaKraj(ts);
i++;
}
in.close();
cout << "Iz datoteke 'imenik2.dat' ucitano je " << n << " zapisa" << endl;
}
else
{
cout<<"Imenik nije ucitan iz datoteke"<<endl;
}
}
//////////////////////////////////////////////////////////////////////////////
int filesize(){
ifstream in;
in.open ("imenik2.dat", ios::binary );
if (in.good()==false) {return 0;}
in.seekg (0, ios::end);
int bajtova = in.tellg();
in.close ();
if (in.good()==false) {cout << "GRESKA: Datoteka se ne moze zatvoriti!\n";}
return bajtova;
}
13

//////////////////////////////////////////////////////////////////////////////
void traziPrezimeC() {
cout<<"Unesite prezime za pretragu: ";
cin>>odgovor;
Cvor *gz;
gz = glava;
while(gz)
{
if (!strcmp(odgovor, gz->Prezime))
{
printf("%d\n", gz->id);
printf("%s\n", gz->Ime);
printf("%s\n", gz->Prezime);
printf("%s\n", gz->Br_tel);
return;
}
else
{
gz = gz->sljedeci;
}
}
printf("Prezime nije nadjeno\n");
}
//////////////////////////////////////////////////////////////////////////////

14

You might also like