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 */
}