/* zadatak broj 8. Srdjan Vesic (085/2000) Ako program pozovete sa: c:\>zad8 < seminarski.txt > seminarski1.txt onda ce datoteka seminarski1.txt predstavljati ispravljenu verziju seminarskog, sto podrazumeva sledece: (1) niske "<" i ">" bice promenjene u "<" i ">" (redom) (2) bice izbrisani svi atributi iz html etiketa (ukljucujuci i one koje su bile ogranicene niskama "<" i ">", ili njihovim kombinacijama sa znakovima "<" i ">"). Izuzetak cine etikete: meta, ident, ident_student itd. (videti kraj zadatka) */ #include #define MANJE "lt;" #define VECE "gt;" #define DM 3 /* duzina oznake lt; */ #define DV 3 /* duzina oznake gt; */ #define MAX 3 /* uzima vecu od ove dve vrednosti */ #define MAXET 50 /* duzina niza u koji se upisuje trenutna etiketa (njen deo do prvog blanka )*/ typedef enum {false, true} boolean; /* deklaracija promenljivih */ boolean uetiketi; /* oznacava da li smo trenutno u etiketi */ char niz[MAX + 1]; /* niz u koji se upisuje niska koja sledi posle znaka "&" */ boolean usred; /* da li smo u sred niza koji je poceo sa & */ boolean preblanka; /* ako smo uetiketi, ova promenljiva govori da li smo prosli prvi blanko (i tako usli u atribute) */ boolean upravoizasao; /* ako je vrednost ove promenljive true, onda je trenutno ucitanom karakteru prethodio niz &xx; */ boolean etiketaukojojsenebrise; /* ako smo u etiketi i ako je etiketaukojojsenebrise == true, onda smo trenutno u nekoj od etiketa: meta, ident, ident_student itd. */ char et[MAXET]; /* niz u koji se upisuje trenutna etiketa */ int etbr; /* brojac za ovaj niz */ boolean upravouet; /* jednaka je "true" ako smo upravo usli u etiketu */ /* deklaracija funkcija */ void Etiketa (int c); boolean JednakiStringovi (char* s1, char* s2); void StampajNiz(void); void Stampanje(int c); boolean Euksnb(void); main () { int c; /* trenutno ucitani znak */ uetiketi = false; preblanka = true; etiketaukojojsenebrise = false; c = 0; while (c != EOF) { c = getchar(); upravoizasao = false; upravouet = false; Etiketa (c); Stampanje(c); } } /* ova funkcija postavlja vrednosti promenjivih uetiketi, usred i upravoizasao, a u slucaju da smo izasli iz niske koja je pocela sa "&" stampa "<", ">" ili sadrzaj same niske, ako nije jednaka ni VECE ni MANJE (npr. stampa "&Cx;") */ void Etiketa (int c) { static int br; /* brojac */ if (uetiketi == true) { /* ako smo u etiketi */ if (usred) { niz[br++] = c; if (br == DV) { /* imamo DV upisanih znakova, pa se pitamo da li su oni = VECE */ niz[DV + 1] = '\0'; if (JednakiStringovi (niz, VECE)) { uetiketi = false; /* ako jesu, izlazimo iz etikete */ usred = false; /* nismo vise u sred niza koji je poceo sa & */ putchar('>'); /* zamenjujemo ">" sa ">" */ upravoizasao = true; } else { usred = false; /* nismo vise u sred niza koji je poceo sa & */ if((preblanka) || (etiketaukojojsenebrise)) { StampajNiz(); upravoizasao = true; } } } else {} } else { if (c == '>') { uetiketi = false; } else { if (c == '&') { usred = true; br = 0; } else {} } } } else { /* ako nismo u etiketi */ /* slicno kao kad smo u etiketi */ if(usred) { niz[br++] = c; if(br == DM) { niz[DM + 1] = '\0'; if(JednakiStringovi(niz, MANJE)) { uetiketi = true; upravouet = true; etiketaukojojsenebrise = false; etbr = 0; preblanka = true; usred = false; putchar('<'); /* zamenjujemo "<" sa "<" */ upravoizasao = true; } else { usred = false; if((preblanka)||(etiketaukojojsenebrise)) { StampajNiz(); upravoizasao = true; } } } else {} } else { /* nismo u sred */ if(c == '<') { uetiketi = true; upravouet = true; etiketaukojojsenebrise = false; etbr = 0; preblanka = true; } else { if(c == '&') { br = 0; usred = true; } else {} } } } } /* ova funkcija vraca true ako su stringovi jednaki, a false ako nisu jednaki */ boolean JednakiStringovi (char* s1, char* s2) { int brojac; for(brojac = 0; s1[brojac] != '\0' && s2[brojac] != '\0'; brojac++) { if(s1[brojac] != s2[brojac]){ return false; } } return (s1[brojac] == '\0' && s2[brojac] == '\0'); } /* ova funkcija stampa niz "niz"; pozivamo je iz funkcije Etiketa, kada dodjemo do kraja niza koji nije jednak ni VECE ni MANJE */ void StampajNiz(void) { int i; putchar('&'); for(i = 0; niz[i] != '\0'; i++) { putchar(niz[i]); } } /* ova funkcija, u zavisnosti od toga da li smo u etiketi, u njenom atributu, ili u sred niza koji je poceo sa "&", stampa niz, ucitani znak (c), ili ne stampa nista (brise atribute) i tome slicno. takodje postavlja vrednost promenljive preblanka, koja se koristi za odredjivanje polozaja u etiketi (da bismo znali da li smo u samoj etiketi, ili u njenim atributima) */ void Stampanje(int c) { if(c != EOF) { if(uetiketi) { if(preblanka) { if(usred) { //uetiketi preblanka usred } else { //uetiketi preblanka nije usred if(c == ' ') { preblanka = false; et[etbr] = '\0'; if (Euksnb()) { etiketaukojojsenebrise = true; putchar(' '); } } else { if (!upravoizasao) { putchar(c); } if(!upravouet) { et[etbr++] = c; } } } } else { if(usred) { //uetiketi posle blanka usred } else { //uetiketi posle blanka nije usred if((etiketaukojojsenebrise)&&(!upravoizasao)) { putchar(c); } } } } else { if (usred) { //ne uetiketi usred } else { //ne uetiketi nije usred if (!upravoizasao) { putchar(c); } } } } } /* ova f-ja treba da odredi da li smo u nekoj od etiketa u kojoj se atributi ne brisu. ako je tako, vraca true; (inace vraca false) */ boolean Euksnb(void) { if((JednakiStringovi(et,"meta")) || (JednakiStringovi(et,"!ident")) || (JednakiStringovi(et,"!ident_autor")) || (JednakiStringovi(et,"!ident_student")) || (JednakiStringovi(et,"!arhiv")) || (JednakiStringovi(et,"!version")) || (JednakiStringovi(et,"!pravo")) || (JednakiStringovi(et,"!naslov")) || (JednakiStringovi(et,"!rod")) || (JednakiStringovi(et,"!kontakt"))) { return true; } else { return false; } }