#include #include #include #include #include /* makro koji se definise u fazi debagovanja */ /* #define DEBUG 1 */ /* maksimalan broj studenata u fajlu */ #define MAX_BR_STUDENATA 64 /* struktura koja nam je potrebna za pamcenje studenata */ typedef struct { char *ime; int br_poena; } student; /* pomocna fja poredjenja koja nam je potrebna zbog sortiranja */ int poredi(const void *s1, const void *s2) { return ((student *) s2)->br_poena - ((student *) s1)->br_poena; } /* glavna fja */ int main() { /* zaglavlje fajla */ char pattern1[] = "[ \n\t]*[ \n\t]*[ \n\t]*.*[ \n\t]*[ \n\t]*[ \n\t]*[ \n\t]*[ \n\t]*.+[ \n\t]*.+[ \n\t]*.+[ \n\t]*.+[ \n\t]*.+[ \n\t]*"; /* red tabele koji se odnosi na jednog studenta */ char pattern2[] = "[ \n\t]*[ \n\t]*([a-zA-Z ]+)[ \n\t]*[ \n\t]*([0-9]+)[ \t\n]*[ \t\n]*[ \n\t]*([0-9]+)[ \t\n]*[ \t\n]*[ \n\t]*([0-9]+)[ \t\n]*[ \t\n]*[ \n\t]*([0-9]+)[ \t\n]*"; /* kraj fajla */ char pattern3[] = "[ \t\n]*[ \n\t]*[ \n\t]*"; /* buffer koji predstavlja tekst koji pretrazujemo */ char *text; /* pokazivac odakle pocinjemo pretragu */ char *p; /* bufferi u koje kopiramo ... */ /* ime i prezime studenta */ char *substring1; /* broj bodova na prvoj predispitnoj obavezi */ char substring2[3]; /* broj bodova na drugoj predispitnoj obavezi */ char substring3[3]; /* broj bodova na trecoj predispitnoj obavezi */ char substring4[3]; /* broj bodova na cetvrtoj predispitnoj obavezi */ char substring5[3]; /* struktura koja je potrebna za pretrazivanje */ regex_t a; /* kod eventualne greske */ int errcode; /* buffer u koji smestamo opis eventualne greske */ char *errbuf; /* niz u kome pamtimo mesto regularnog izraza u tekstu */ regmatch_t match[6]; /* fajl iz kog citamo ulaz */ FILE *f; /* velicina fajla */ int velicina_fajla; /* niz studenata u koji pamatimo imena sa ukupnim poenima */ student studenti[MAX_BR_STUDENATA]; /* trenutni broj studenata */ int trenutni_br_studenata = 0; /* brojac */ int i; /* otvaramo fajl */ if ((f = fopen("rezultati.html", "r")) == NULL) { fprintf(stderr, "Greska pri otvaranju fajla\n"); exit(EXIT_FAILURE); } /* pozicioniramo se na kraj fajla da bi procitali njegovu velicinu */ if (fseek(f, 0, SEEK_END) != 0) { fprintf(stderr, "Greska pri pozicioniranju u fajlu\n"); exit(EXIT_FAILURE); } /* citamo velicinu fajla */ velicina_fajla = ftell(f); /* premotavamo fajl na pocetak */ if (fseek(f, 0, SEEK_SET) != 0) { fprintf(stderr, "Greska pri pozicioniranju u fajlu\n"); exit(EXIT_FAILURE); } /* alociramo buffer potreban za smestanje sadrzaja fajla */ if ((text = (char *) malloc(velicina_fajla)) == NULL) { fprintf(stderr, "Nedovolno memorije\n"); exit(EXIT_FAILURE); } /* ucitavamo fajl, liniju po liniju, sto je malo manje efikasno */ p = text; while (fgets(p, 10000, f) != NULL) p = text + strlen(text); /* po ucitavanju fajla, ga zatvaramo */ fclose(f); /* pretrazivacemo text pocevsi od p */ p = text; /* pripremamo strukturu za pretragu zaglavlja fajla */ errcode = regcomp(&a, pattern1, REG_EXTENDED | REG_NEWLINE); /* proveravano da li je doslo do nekakve greske */ if (errcode != 0) { int errbuf_size = regerror(errcode, &a, NULL, 0); if ((errbuf = (char *) malloc(errbuf_size)) == NULL) fprintf(stderr, "Nema dovoljno memorije\n"); regerror(errcode, &a, errbuf, errbuf_size); fprintf(stderr, "%s\n", errbuf); exit(EXIT_FAILURE); } /* u fajlu trazimo odgovarajuci pocetak */ if (regexec(&a, p, 1, match, 0) != 0) { printf("Fajl nema potrebno zaglavlje\n"); } /* oslobadjamo nepotrebnu strukturu */ regfree(&a); /* dalju pretragu nastavljamo tamo gde je nadjen kraj zaglavlja */ p += match[0].rm_eo; /* pripremamo strukturu za pretragu redova tabele sa studetima */ errcode = regcomp(&a, pattern2, REG_EXTENDED | REG_NEWLINE); /* proveravano da li je doslo do nekakve greske */ if (errcode != 0) { int errbuf_size = regerror(errcode, &a, NULL, 0); if ((errbuf = (char *) malloc(errbuf_size)) == NULL) fprintf(stderr, "Nema dovoljno memorije\n"); regerror(errcode, &a, errbuf, errbuf_size); fprintf(stderr, "%s\n", errbuf); exit(EXIT_FAILURE); } /* dok postoje redovi tabele sa studentima, nalazimo ih */ while (regexec(&a, p, 6, match, 0) == 0) { /* aloriramo memoriju za ime i prezime studenta i kopiramo ga */ if ((substring1 = (char *) malloc(match[1].rm_eo - match[1].rm_so + 1)) == NULL) { fprintf(stderr, "Nedovolno memorije\n"); exit(EXIT_FAILURE); } strncpy(substring1, p + match[1].rm_so, match[1].rm_eo - match[1].rm_so); substring1[match[1].rm_eo - match[1].rm_so] = '\0'; /* kopiramo broj bodova sa prve predispitne obaveze */ strncpy(substring2, p + match[2].rm_so, match[2].rm_eo - match[2].rm_so); substring2[match[2].rm_eo - match[2].rm_so] = '\0'; /* kopiramo broj bodova sa druge predispitne obaveze */ strncpy(substring3, p + match[3].rm_so, match[3].rm_eo - match[3].rm_so); substring3[match[3].rm_eo - match[3].rm_so] = '\0'; /* kopiramo broj bodova sa trece predispitne obaveze */ strncpy(substring4, p + match[4].rm_so, match[4].rm_eo - match[4].rm_so); substring4[match[4].rm_eo - match[4].rm_so] = '\0'; /* kopiramo broj bodova sa cetvrte predispitne obaveze */ strncpy(substring5, p + match[5].rm_so, match[5].rm_eo - match[5].rm_so); substring5[match[5].rm_eo - match[5].rm_so] = '\0'; /* efikasnije od kopiranja bi bilo samo pamcenje broja poena * ali je izabran ovaj nacin zbog edukativnog pristupa. * Ovo bi bilo efikasnije: * int br_poena1 = atoi(p + match[1].rm_so); * int br_poena2 = atoi(p + match[2].rm_so); * int br_poena3 = atoi(p + match[3].rm_so); * int br_poena4 = atoi(p + match[4].rm_so); */ /* radi kontrole stampamo procitanog studenta */ #ifdef DEBUG printf("Student: %s, %d, %d, %d, %d\n", substring1, atoi(substring2), atoi(substring3), atoi(substring4), atoi(substring5)); #endif /* ako ima mesta, pamtimo procitanog studenta */ if (trenutni_br_studenata >= MAX_BR_STUDENATA) fprintf(stderr, "Nema dovoljno mesta za ovog studenta"); else { if ((studenti[trenutni_br_studenata].ime = (char *) malloc(strlen(substring1) + 1)) == NULL) { fprintf(stderr, "Nedovoljno memorije\n"); exit(EXIT_FAILURE); } strcpy(studenti[trenutni_br_studenata].ime, substring1); studenti[trenutni_br_studenata++].br_poena = atoi(substring2) + atoi(substring3) + atoi(substring4) + atoi(substring5); } /* dalju pretragu nastavljamo poste poslednjeg procitanog studenta */ p += match[0].rm_eo; /* oslobadjano buffer sa imenom i prezimenom procitanog studenta */ free(substring1); } /* oslobadjano nepotrebnu sturkturu */ regfree(&a); /* pripremamo strukturu za pretragu kraja fajla */ errcode = regcomp(&a, pattern3, REG_EXTENDED | REG_NEWLINE); /* proveravano da li je doslo do nekakve greske */ if (errcode != 0) { int errbuf_size = regerror(errcode, &a, NULL, 0); if ((errbuf = (char *) malloc(errbuf_size)) == NULL) fprintf(stderr, "Nema dovoljno memorije\n"); regerror(errcode, &a, errbuf, errbuf_size); fprintf(stderr, "%s\n", errbuf); exit(EXIT_FAILURE); } /* proceravano da li kraj fajla ima odgovarajuci format */ if (regexec(&a, p, 1, match, 0) != 0) { printf("Fajl nema ispravan kraj\n"); } /* oslobadjano buffer sa sadrzajem fajla */ free(text); /* oslobadjamo nepotrebnu strukturu */ regfree(&a); /* sortirano niz studenta po ukupnom broju poena */ qsort(studenti, trenutni_br_studenata, sizeof(student), &poredi); /* ispisujemo sortirane studente sa njihovim ukupnim brojem poena */ for (i = 0; i < trenutni_br_studenata; i++) printf("%s - %d\n", studenti[i].ime, studenti[i].br_poena); /* oslobadjamo memoriju alociranu za imena studenata */ for (i = 0; i < trenutni_br_studenata; i++) free(studenti[i].ime); /* uspesno zavrsavamo program */ return EXIT_SUCCESS; }