/* zadatak: 14. ime programa: veze resenje: Srdjan Vesic (085/2000) Program se poziva sa: veze kljucna_rec tekst_u_kom_se_pretrazuje Npr: veze kocka seminarski.txt Rezultat rada programa je datoteka svzad014.html. VAZNO ukoliko na direktorijumu na kom se nalazi "Quickc" UPOZORENJE: imate datoteku koja se zove "svzad014.html", njen sadrzaj ce posle izvrsavanja ovog programa biti unisten! Ako zelite da Vasa kljucna rec bude pronadjena i kada se pojavi unutar druge reci (npr. "kockast") nakon sto aktivirate program, izaberite trazenje unutar reci. Ako ne odgovorite sa 'd', podrazumeva se da ne zelite trazenje unutar reci, i Vasa rec ce biti pronadjena samo ako je razdvojena separatorima od okolnih reci. (npr. "To je bila prava kocka.") Separatori su: \n \t . , ! ? : ' " - (Znak ";" nije racunat kao separator da biste mogli da nalazite reci kao sto je "pra&sx;ina".) */ #include #define MAXKLJUCNAREC 100 /* maksimalna dozvoljena duzina klucne reci */ #define MAXTRENUTNAREC 1000 /* maksimalna dozvoljena duzina reci u tekstu */ #define MAXTRENUTNAREC1 1000 /* granica za niz u koji se "pakuje" deo po deo datoteke; mora da bude veci od MAXKLJUCNAREC */ typedef enum {false, true} boolean; int rednibroj = 0; /* broji koliko puta se pojavila kljucna rec */ boolean opciono; /* ako je true, naci ce se kljucna rec cak iako je unutar neke niske; ako je false, kljucna rec ce se naci samo ako je razdvojena separatorima */ int duzinakljucnereci; char kljucnarec[MAXKLJUCNAREC + 1]; /* niz koji sadrzi klucnu rec */ void Vezivanje (FILE* ulaz, FILE* izlaz); void OpcVezivanje(FILE* ulaz, FILE* izlaz); boolean JednakiStringovi (char* s1, char* s2); boolean Separator (int c); main (int argc, char* argv[]) { int c; char opc; char stop; FILE* ulaz; FILE* izlaz; /* provera (da li su tacno 3 argumenta u komandnoj liniji) */ if (argc != 3) { fprintf(stderr, "\nNepravilno pozvan program!\n"); fprintf(stderr, "Posetite: www.matf.bg.ac.yu/nastavno/dvitas/nastava/op/zadaci/zadaci.html"); return 0; } /* provera (da li je duzina kljucne reci manja ili jednaka dozvojenoj) */ duzinakljucnereci = strlen(argv[1]); if (duzinakljucnereci > MAXKLJUCNAREC) { fprintf (stderr, "\nPredugacka kljucna rec! Povecaj MAXKLJUCNAREC."); return 0; } printf("\nZelite li da se trazi i unutar reci? (d = da, ostalo = ne)\n"); scanf("%c", &opc); if (opc == 'd') { opciono = true; } else { opciono = false; } /* punimo niz kljucnarec: */ for (c = 0; (argv[1][c] != '\0') && (c < MAXKLJUCNAREC); c++) { kljucnarec[c] = argv[1][c]; } kljucnarec[c] = '\0'; /* otvaranje datoteka: */ if ((ulaz = fopen(argv[2], "r")) == NULL) { fprintf (stderr, "\nNemoguce otvoriti datoteku %s!", argv[2]); } if ((izlaz = fopen("svzad014.html", "w")) == NULL) { fprintf (stderr, "\nNemoguce otvoriti datoteku svzad014.html!"); } if (opciono) { OpcVezivanje(ulaz, izlaz); } else { Vezivanje(ulaz, izlaz); } if(rednibroj == 0) { fprintf(stderr, "\nKljucna rec koju ste naveli se ne pojavljuje u datoteci koju pretrazujete."); } else { fprintf(stderr, "\nKljucna rec se pojavila %d put%s.", rednibroj, (((rednibroj % 10) == 1) && ( (rednibroj % 100) != 11 )) ? "" : "a"); } fprintf (izlaz, " Kliknite ovde ako zelite da posaljete poruku autoru programa. "); if (fclose(izlaz) == EOF) { fprintf (stderr, "\nNemoguce zatvoriti datoteku svzad014.html!"); } if (fclose(ulaz) == EOF) { fprintf (stderr, "\nNemoguce zatvoriti datoteku %s!", argv[2]); } } void Vezivanje(FILE* ulaz, FILE* izlaz) { static int c = 0; /* trenutno ucitani znak */ static int i = 0; /* brojac */ char trenutnarec[MAXTRENUTNAREC + 1]; /* trenutno ucitana rec */ while(c != EOF) { c = getc(ulaz); if (Separator(c)) { trenutnarec[i] = '\0'; if (JednakiStringovi (trenutnarec, "")) { fprintf(izlaz, "%c", c); i = 0; } else if (JednakiStringovi (trenutnarec, kljucnarec)) { fprintf(izlaz, "%s%c", rednibroj, rednibroj + 1, trenutnarec, c); rednibroj++; i = 0; } else { fprintf(izlaz, "%s%c", trenutnarec, c); i = 0; } } else { /* ako nije separator */ if (i < MAXTRENUTNAREC) { trenutnarec[i] = c; i++; } else { fprintf (stderr, "\nPredugacka rec! Povecaj MAXTRENUTNAREC!"); exit (1); } } } } 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'); } /* vraca: true, ako je c jedan od: ' ' '\n' itd. false, inace */ boolean Separator (int c) { int i; char niz[] = " \n\t.,!?:'\"-"; for (i = 0; niz[i] != '\0'; i++) if (c == niz[i]) return true; return false; } void OpcVezivanje(FILE* ulaz, FILE* izlaz) { int l; static int c = 0; /* trenutno ucitani znak */ static int i = 0; /* brojac */ char trenutnarec[MAXTRENUTNAREC1 + 1]; /* trenutno ucitani niz karaktera */ boolean menjao = false; /* punimo trenutnarec iz datoteke: */ while (1) { for (i = 0; (c != EOF) && (i < MAXTRENUTNAREC1); i++) { trenutnarec[i] = (c = getc(ulaz)); } i--; if (i >= MAXTRENUTNAREC) { } else { trenutnarec[i] = -1; } i = 0; while (i < duzinakljucnereci) { if (trenutnarec[i] == -1) { trenutnarec[i] = '\0'; fprintf (izlaz, "%s", trenutnarec); } i++; } /* glavni deo */ for (i = 0; (i <= (MAXTRENUTNAREC1 - duzinakljucnereci)) && trenutnarec[i + duzinakljucnereci] != -1; i++) { if (Poredi ("", trenutnarec, i, 6)) { /* 6 je duzina niske: */ fprintf (izlaz, ""); i += 5; /* 6 - 1 */ menjao = true; } else if ((menjao) && (Poredi (kljucnarec, trenutnarec, i, duzinakljucnereci))) { fprintf(izlaz, "%s", rednibroj, rednibroj + 1, kljucnarec); rednibroj++; for (l = 0; l < duzinakljucnereci; l++) { if (trenutnarec[i + l] == -1) { trenutnarec[i + l] = '\0'; fprintf (izlaz, "%s", trenutnarec); return; } } i += duzinakljucnereci - 1; } else { fprintf(izlaz, "%c", trenutnarec[i]); } } if (c == EOF) { if (Poredi (kljucnarec, trenutnarec, i, duzinakljucnereci)) { fprintf(izlaz, "%s", rednibroj, rednibroj + 1, kljucnarec); rednibroj++; return; } else { for (l = 0; l < duzinakljucnereci; l++) { fprintf (izlaz, "%c", trenutnarec[i + l]); } return; } } else { for (l = 0; i + l < MAXTRENUTNAREC1; l++) { trenutnarec[l] = trenutnarec[i + l]; } } } } /* uzima dva stringa; poredjenje se vrsi na sledeci nacin: poredi se od 0-tog do (koliko-1)-vog karaktera iz prvog stringa sa od odakle-og do (odakle+koliko-1)-vog karaktera iz drugog vraca: true, ako su jednaki false, ako nisu */ boolean Poredi (char* prvi, char* drugi, int odakle, int koliko) { int brojac; for (brojac = 0; brojac < koliko; brojac++) { if (prvi[brojac] != drugi[odakle + brojac]) { return false; } } return true; }