Code:
#include <stdio.h>
#include <stdlib.h>
Za koriscenje "string" funkcija iz standardne biblioteke C-a, pravilno je da prethodno ukljucis i 'string.h' zaglavlje.
Code:
void ukljuci(char a, char *s, char d)
{
/*Funkcija ukljuci sluzi za ukljucivanje novog procitanog znaka u buffer*/
int i;
for (i = 1; i < d; i++) {
*(s + i - 1) = *(s + i);
*(s + i) = a;
}
Ako je potrebno 'a' promenljivu dodati na kraj onda ona ne mora da se stalno dodaje u petlji vec moze izvan petlje (ispod 'for' bloka) da se napise ta dodela koja ce se izvrsiti samo jednom.
Code:
}
void smanji(char *s)
{
/*Funkcija smanji sluzi za pretvaranje eventualnih velikih slova u niski u mala*/
char i, l;
for (i = 0, l = 0; i < strlen(s); i++) {
l = 0;
l = isupper(*(s + i));
if (l)
*(s + i) += 32;
Umesto "konstante" 32, bolje koristi izraz ('a' - 'A')
Code:
}
};
void main(int bpar, const char *vpar[])
{
/*Argumenti programa su niska karaktera koja se trazi, i fajl u kome se ta niska trazi */
int i, v, r = 1;
Za duzinu niza u funkcijama iznad si koristio char (1 bajt) promenljivu dok ovde duzinu reci prosledjene programu cuvas u int (2-4 bajta) ovo nije dobra praksa jer nepaznjom moze doci do greske.
Code:
char c, *rec, *buffer;
FILE *mf;
v = strlen(*vpar[1]);
Ovde funkciji 'strlen()' predajes prvi karakter druge reci, a ne drugu rec (niz). Trebao si dakle da napises:
v = strlen(vpar[1]);
Zapamti i da funkcija 'strlen()' vraca samo broj znakova u reci bez uracunatog nula terminirajuceg znaka.
Code:
rec = malloc(v);
Ovde promenjvivoj 'v' trebas da dodas broj 1 kako bi rezervisao mesto i za nula terminirajuci znak.
Code:
rec = vpar[1];
'vpar[1]' vraca pokazivac (vpar je pokazivac na pokazivace) tj, adresu, u liniji iznad ti si rezervisao memoriju za rec ali si ovim dodavanjem tu memoriju "ignorisao" i postavio si da 'rec' pokazuje (jer 'rec' je pokazivac) na istu onu memoriju na koju pokazuje i 'vpar[1]'. Ovde si trebao da kopiras sadrzaj iz jednoj niza u drugi ako si vec resio da koristis promenljivu 'rec'. Znaci npr ovako:
strncpy(rec, vpar[1], v + 1);
Obrati paznju da je promenjlivoj 'v' opet dodat broj 1 jer se bez toga nece kopirati i nula terminirajuci znak.
Code:
smanji(rec);
buffer = malloc(v);
U ovom konkretnom slucaju nije bitno jer se u funkciji 'ukljuci()' koju pozivas ispod, niz puni od kraja, ali ipak obrati paznju da clanovi niza 'buffer' nisu garantovano inicijalizovani, tj. mogu da sadrze bilo sta. Da bi inicijalizovao clanove niza na nulu, ispod linije iznad napisi:
memset(buffer, 0, v);
ili umesto funkcije 'malloc()' koristi funckiju 'calloc()' koja automatski vraca niz ciji su clanovi inicijalizovani na nulu:
buffer = calloc(v, sizeof(char));
Code:
mf = fopen(vpar[2], "r"); /* C:\Mojfajl.txt */
while ((c = fgetc(mf)) != EOF) {
ukljuci(c, buffer, v);
smanji(buffer);
Umesto sto koristis funkciju koja opet prolazi kroz ceo niz i proverava i one znakove koji su provereni i prevedeni u mala slova, mogao bi da napises funkciju koja bi smanjivala samo taj karakter koji si dobio iz datoteke. Funkcija bi npr. mogla da izgleda ovako:
char smanji(char c) {
if (isupper(c)) return c + 'a' - 'A';
else return c;
}
Code:
r = strcmp(rec, buffer);
Kako 'buffer' ne sadrzi nula terminirajuci znak na kraju, na sta se oslanjaju mnoge funkcije za rad sa znakovnim nizovima iz standardne biblioteke C-a medju kojima je i funkcija 'strcmp()', ona ce u slucaju kada su u pitanju iste reci, u promenljivama 'rec' i 'buffer' porediti znakove dok ne naidje na nula terminirajuci znak u drugoj promenljivoj ili dok se ne pronadju razliciti karakteri, a niz 'buffer' nema na kraju nula terminirajuci znak. Umesto toga trebao bi da kao drugu promenljivu prosledis 'rec' ili jos bolje da koristis funkciju 'strncmp()' koja poredi samo naznaceni broj karaktera. Dakle:
r = strncmp(rec, buffer, v);
Code:
if (!r)
break;
}
if (!r)
printf("U tekstualnom fajlu postoji niska znakova: %s !\n",
vpar[1]);
else
printf("U tekstualnom fajlu NE postoji niska znakova: %s !\n",
vpar[1]);
free(buffer);
A promenljiva 'rec'? ;) Znaci trebalo je da se napise i:
free(rec);
Mada posto se izlazi iz programa nije ni mnogo bitno jer ce operativni sistem ionako sam da oslobodi svu zauzetu memoriju.
Code:
fclose(mf);
system("PAUSE");
Ovo ce ti raditi samo na Vindouz sistemu, ili na onim sistemima gde postoji komanda ljuske 'pause'.
Code:
}
U vaznijem programu bila bi potrebna provera vrednosti kako bi se izbegle greske tokom izvrsavanja programa. Na primer, trebalo bi da se proveri da li su programu prosledjeni onoliko i oni parametri koje ocekujes, da li 'mf' nakon poziva funkcije 'fopen()' sadrzi 'NULL', sto ukazuje na gresku pri otvaranju, da li pokazivaci 'rec' i 'buffer' sadrze 'NULL' nakon alociranja memorije, sto opet ukazuje na gresku i da li je funkcija 'fclose' vratila nulu ili 'EOF', sto pogadjas :) ponovo ukazuje na gresku pri zatvranju datoteke.
E da, ako vec nameravas da koristis srpske nazive za imena promenljivih i funkcija onda ostani dosledan :)
Srecno :)