Napisati C program koji će iz datoteke prva.htm prepisati nazive međusobno različitih otvarajućih etiketa (bez atributa) u binarno stablo pretrage i potom: a) štampati sadržaj drveta u infiksnom poretku u datoteci izlaz.txt, ako je kao parametar komandne linije zadata opcija -t b) na standardni izlaz ispisati ukupan broj čvorova drveta, ako je kao parametar komandne linije zadata opcija -u Obezbediti da program radi i kada su prisutni svi opcioni argumenti. Pretpostaviti da naziv otvarajuće etikete nije duži od 20 karaktera. Primer:



Nova slika

Otvarajuće etikete bez atributa su: BR, IMG, P #include #include #include #include #define MAXREC 21 #define TRUE 1 #define FALSE 0 typedef struct drvo_tag { char *rec; /* rec teksta */ struct drvo_tag *levo; /* leva grana */ struct drvo_tag *desno; /* desna grana */ } drvo; /* Funkcije */ drvo *addtree(drvo *, char *); /* ubacuje rec u drvo */ void treeprint(drvo *); /* stampa drvo – infiksni poredak za BSP*/ int uzmi_tag(FILE *f, char *s, int k); /* ucitava tagove (do k karaktera) iz datoteke u nisku s*/ drvo *talloc( void ); /* alokacija cvora BSP */ char *strdpl(char *s); /* kreira kopiju niske s */ void osloboditi( drvo *k); /* oslobadja zauzeti prostor za drvo */ int brcvorova(drvo *k); /* vraca broj cvorova stabla */ /*glavni program*/ main(int argc, char *argv[]) { drvo *koren; /*koren stabla pretrazivanja */ char rec[MAXREC]; /*sadrzaj reci sa ulaza */ FILE *ulaz; int i,j; /* brojacke promenljive */ int node=FALSE, printt=FALSE; /*indikatori postojanja opcija u komandnoj liniji */ ulaz=fopen("prva.htm","rt"); if (ulaz==NULL) exit(1); /*prosledjivanje argumenata komandne linije */ for (i = 1; i < argc && argv[i][0] == '-'; i++) { /*prosledjivanje opcija ili niti jedne korektne opcije ili od jedne do cetiri opcije*/ for (j=1; argv[i][j] !='\0'; j++) { /* test prisustva opcionih argumenata -n, -l, -d,-p */ switch (argv[i][j]) { case 'u': node = TRUE; break; case 't': printt=TRUE; break; default: fprintf(stderr, "Nekorektan opcioni argument '%s'\n", argv[i]); return EXIT_FAILURE; } } } /*ucitavanje reci ciji broj pojavljivanja se broji */ koren = NULL; while( 1 ) { int kraj = uzmi_tag(ulaz,rec, MAXREC); /*dodavanje cvora u stablo cvora, ako rec ne postoji u stablu */ if ( strlen(rec)) koren = addtree( koren, rec); if(kraj == EOF) break; /*ucitavanje se vrsi do markera kraja */ } fclose(ulaz); /*stampanje broja cvorova stabla */ if (node) printf("\nCvorova: %d", brcvorova(koren)); /*stampanje sadrzaja stabla*/ if (printt) treeprint(koren); /*oslobadjanje zauzetog prostora za stablo pretrage */ osloboditi(koren); return 0; } /* addtree - dodaje cvor sa tekstom na koji pokazuje w, na ili ispod p u drvetu*/ drvo *addtree( drvo *p, char *w ) { int cond; if( p == NULL ) /* naisla nova rec */ { p = talloc(); p->rec = strdpl(w); p->levo = p->desno = NULL; } else if ((cond = strcmp(w,p->rec))< 0 ) /*manja rec => levi ogranak*/ p->levo = addtree(p->levo, w); else if (cond >0) /*vece =>desni ogranak*/ p->desno = addtree(p->desno, w); return p; } void treeprint(drvo *p) /* treeprint - rekurzivno stampanje drveta*/ { if( p != NULL ) { treeprint( p->levo ); printf("%s\n", p->rec ); treeprint( p->desno ); } } int uzmi_tag(FILE *f,char s[], int lim) { char c; int i = 0; /* preskociti sve znake do znaka <*/ while( ( (c =fgetc(f)) != '<') && c!=EOF); if( c==EOF ) {s[0] = '\0'; return EOF;} /* prazna rec i vratiti EOF */ /* ucitati ostatak etikete; OBRATITI PAZNJU DA HTML JE CASE INSENSITIVE, A DA f-ja strcmp pravi razliku u velicini slova, tj. i
su 2 pojave iste etikete*/ while( (c = fgetc(f)) != EOF && isalnum(c) && i < lim) {s[i] = toupper(c); i++; } s[++i] = '\0'; /* zavrsiti nisku */ if( c==EOF ) return EOF; return i; } int brcvorova(drvo *c) { if(c == NULL) return 0; else return 1+brcvorova(c->levo)+brcvorova(c->desno); } drvo *talloc(void) { return (drvo *) malloc(sizeof(drvo)); } char *strdpl(char *s) /* pravi se kopija niske s */ { char *p; p = (char *) malloc(strlen(s) + 1 ); if( p != NULL ) strcpy(p,s); return p; } void osloboditi( drvo *k) { /*rekurzivno se oslobadja levo i desno podstablo korena zadatog stabla */ if (k->levo) osloboditi (k->levo); if (k->desno) osloboditi (k->desno); free (k); /*brisanje cvora koji predstavlja koren zadatog stabla */ }