Download as pdf or txt
Download as pdf or txt
You are on page 1of 14

Argumenti komandne linije i rad sa proizvoljnim datotekama

Prilikom pozivanja programa iz komandne linije moguće je navesti određene opcije i argumente,
koje program koristi u svom radu. Npr, možemo pozvati program na sledeći način:
./izvrsni ulaz.txt izlaz.txt
zeleci da program izvrsni iskopira fajl ulaz.txt u fajl izlaz.txt.

Potrebno je da postoji mehanizam da program iznutra pristupi stringovima koje je korisnik naveo
prilikom poziva programa.
U C-u se to ostvaruje na sledeći način:
Definišemo parametre funkcije main:
int argc
ovaj parametar prilikom pokretanja programa dobija vrednost broja argumenata koje je korisnik prilikom
poziva naveo. Pri tom se i ime programa broji kao argument komandne linije. U
gornjem primeru će argc biti postavljeno na 3.
char **argv
pokazivač na pokazivač na char koji sadrži adresu prvog u nizu pokazivača na karaktere. Svaki od tih
pokazivača na karaktere sadrži adresu odgovarajućeg stringa koji sadrži argument komandne linije. Npr. u
gornjem primeru, argv[0] će nam pokazivati na string "./primer", argv[1] će nam pokazivati na
string "ulaz.txt", argv[2] će nam pokazivati na string "izlaz.txt". Dakle, niz pokazivača na čiji prvi član
pokazuje argv je dužine upravo argc.

1. NCP koji ispisuje broj argumenata komandne linije i parametre komandne linije.

#include <stdio.h>

/*argumenti komandne linije */


main(int argc, char *argv[] )
{ int i; /*brojac u petlji */
printf("Broj argumenata je %d\n", argc);
/*stampanje svakog argumenta u zasebnom redu */
for(i=0;i<argc;i++)
printf( "argv[%d] = %s\n", i , argv[i] );
}

Pristup proizvoljnoj datoteci u C-u

U C-u se sa fajlovima barata na sledeci nacin:


u standardnoj biblioteci postoji definisana struktura:

typedef struct {

....

} FILE;

koja sadrzi sve informacije vezane za otvoreni fajl. Ove informacije su platformski zavisne, i nama nisu od znacaja.

● Njima barataju funkcije standardne biblioteke.

Fajl se otvara funkcijom:

FILE * fopen(char *ime, char *nacin);

Ova funkcija prihvata string sa putanjom do fajla (ime), kao i string (nacin) koji definise način rada sa fajlom. Može
biti:

"r" fajl se otvara za čitanje (mora da postoji)

"w" fajl se otvara za pisanje (kreira se ako ne postoji, a ako postoji, njegov sadržaj se briše)

"a" fajl se otvara za dopisivanje (kreira se ako ne postoji. Prilikom svakog pisanja sadržaj se dodaje na kraj fajla).

Funkcija fopen() vraca pokazivač na FILE strukturu koja je povezana sa otvorenim fajlom. Od tog trenutka se
baratanje sa otvorenim fajlom sastoji u tome da se funkcijama standardne biblioteke prosledi ovaj pokazivač kao
argument. Ostalo obavlja biblioteka za nas.

● Ako fajl nije uspešno otvoren, povratna vrednost fje je NULL.

Ova konstanta je definisana u stdio.h zaglavlju na sledeći način: #define NULL 0

● Dakle, u pitanju je nula. Uobičajeno je da se ova konstanta koristi za pokazivače koji imaju vrednost nula (tj. ne
pokazuju ni na šta).

Prilikom svakog otvaranja fajla, treba proveriti da li je nastupila greška, tj. da li je povratna vrednost funkcije bila
NULL. Ako jeste, treba nekako obraditi tu grešku. Najčešći način za to je obavestiti korisnika o tome šta se desilo i
prekinuti program.

● Nakon završetka rada sa fajlom, treba ga zatvoriti:

fclose(f);

gde je f FILE pokazivač.

● Prilikom završetka rada programa, svi fajlovi se automatski zatvaraju. Mi se nećemo oslanjati na ovo, već kad god
nam otvoreni fajl više ne treba, eksplicitno ćemo ga zatvarati.

Standardni ulaz i izlaz se u C-u takođe svodi na ulaz i izlaz fajova. Prilikom pokretanja programa se automatski
otvaraju tri fajla, kojima se dodeljuju sledeći globalni FILE pokazivači:

stdin standardni ulaz (povezan sa tastaturom)

stdout standardni izlaz (povezan sa ekranom)


stderr standardni izlaz za greske (povezan sa ekranom)

Još neke funkcije standardne bibilioteke koje barataju sa fajlovima:

int fgetc(FILE *f);

Učitava jedan karakter iz fajla na koji pokazuje f, i vraća njegov ASCII kod kao povratnu vrednost. Ako je nastupio

kraj fajla, vraća EOF.

int fputc(int c, FILE *f);

Upisuje karakter c u fajl na koji pokazuje f. Vraća c.

● Imajući ovo u vidu, lako je uočiti da su sledeće naredbe ekvivalentne:


getchar() <=> fgetc(stdin)
putchar(c) <=> fputc(c, stdout);

char *fgets(char *s, int size, FILE *f);

Učitava celu liniju karaktera iz fajla na koji pokazuje f u string s, ali ne više od size karaktera (što treba da bude
veličina stringa s). Eventualni '\n' sa kraja linije se čuva u stringu s, koji se ovom fjom i terminira nulom. Fja vraća
NULL ako se desila greška pri učitavanju.

int fputs(const char *s, FILE *f);

Upisuje string s u fajl na koji pokazuje f bez terminirajuće nule. Vraća EOF za grešku.

int fscanf(FILE *f, const char *format, ...);

int fprintf(FILE *f, const char *format, ...);

Ove dve funkcije rade isto što i scanf i printf, osim toga što ne rade sa standardnim ulazom, tj. sa standardnim
izlazom već rade sa fajlom na koga pokazuje f.

long ftell(FILE *f);

Ova fja vraća tekuću poziciju datoteke f ili -1L u slučaju greške.

int fseek(FILE *f, long offset, int origin);

Funkcija fseek podešava poziciju datoteke f. Narednim čitanjem ili pisanjem pristupa se podacima na početku nove
pozicije. Nova pozicija se postavlja na offset znakova od mesta origin, koje može biti SEEK_SET (početak datoteke),
SEEK_CUR (tekuća pozicija) ili SEEK_END (kraj datoteke).
Za tekstualnu datoteku, offset mora biti nula ili vrednost koju je
vratila funkcija ftell i u tom slučaju origin mora biti SEEK_SET.

Funkcija fseek vraća vrednost različitu od nule u slučaju greške.

Primer: fseek(f, 0, SEEK_END) postavlja datoteku na 0 bajtova od kraja datoteke, tj. na kraj datoteke.

2. Napisati program koji kopira fajl koji se zada kao prvi argument komandne linije u fajl koji se zada kao drugi
argument komandne linije.

#include <stdio.h>

/* Maksimalna duzina linije */


#define MAX_LINIJE 256

int main(int argc, char *argv[])


{
FILE *in, *out;
char s[MAX_LINIJE];

if (argc != 3) {
fprintf(stderr, "Koriscenje programa: ./copy ulaz izraz\n");
return 1;
}

/* Otvaramo ulazni fajl za citanje */


in = fopen(argv[1], "r");

/* Ako je nastupila greska (fajl ne postoji ili nemamo


pravo citanja) prekidamo program. */
if (in == NULL) {
fprintf(stderr, "Greska prilikom otvaranja fajla\n");
return 1;
}

/* Otvaramo izlazni fajl za pisanje */


out = fopen(argv[2], "w");

/* Ako je nastupila greska (nemamo pravo pisanja, ili


ne mozemo da kreiramo fajl) prekidamo program */
if (out == NULL) {
fprintf(stderr, "Greska prilikom otvaranja fajla\n");
return 1;
}

/* Prepisujemo ulazni fajl u izlazni */


while (fgets(s, MAX_LINIJE, in) != NULL)
fputs(s, out);

/* Zatvaramo fajlove */
fclose(in);
fclose(out);

return 0;
}

3. Napisati program koji prepisuje datoteku cije se ime navodi kao prvi argument komandne linije u datoteku ciji se
argument navodi kao drugi argument komandne linije programa. Ukoliko je navedena opcija -u program prilikom
prepisivanja treba da zamenjuje sva mala slova velikim, a ukoliko je navedena opcija -l sva velika slova se zamenjuju
malim.

(Koliko se ovaj problem teze implementira u odnosu na problem kod koga su fiksirana imena datoteka. Diskutovati
varijantu u kojoj je fiksiran polozaj opcije u listi argumenata, kao i varijantu u kojoj se opcija moze navesti na
proizvoljnom mestu u listi argumenata.)

#include <stdio.h>
#include <ctype.h>

int main(int argc, char **argv)


{
int c;
int velika_u_mala = 0, mala_u_velika = 0;
FILE *in = stdin, *out = stdout;

/* Ocitavamo opcije i argumente prilikom poziva programa */


for (argv++, argc--; argc; argv++, argc--) {
/* Ako je u pitanju opcija... */
if (**argv == '-') {
switch (*++*argv) {
case 'l':
velika_u_mala = 1;
break;
case 'u':
mala_u_velika = 1;
break;
default:
fprintf(stderr, "Pogresna opcija -%c\n", **argv);
return 1;
break;
}
}
/* Ako je u pitanju argument, prvi medju njima je ulazni fajl */
else if (in == stdin) {
if ((in = fopen(*argv, "r")) == NULL) {
fprintf(stderr, "Greska prilikom otvaranja fajla %s\n",
*argv);
return 1;
}
}
/* Drugi argument (ako postoji) je izlazni fajl */
else if (out == stdout) {
if ((out = fopen(*argv, "w")) == NULL) {
fprintf(stderr, "Greska prilikom otvaranja fajla %s\n",
*argv);
return 1;
}
}
/* Ignorisu se suvisni argumenti */
else {
printf("Suvisan argument %s -- ignorisan\n", *argv);
}

/* Ako ne postoje argumenti na komandnoj liniji, tada pokazivaci


in i out ostaju na svojim inicijalnim vrednostima, cime se
citanje vrsi sa standardnog ulaza, a rezultat se ispisuje na
standardni izlaz.
*/

/* Prepisujemo ulaz na izlaz, uz eventualne konverzije */


while ((c = fgetc(in)) != EOF) {
if (islower(c) && mala_u_velika)
fputc(toupper(c), out);
else if (isupper(c) && velika_u_mala)
fputc(tolower(c), out);
else
fputc(c, out);
}

/* Zatvaramo otvorene fajlove */


fclose(in);
fclose(out);

return 0;
}
4. /* find_str [-n|-x] pattern */

Argumenti komandne linije su: poziv programa, opcioni argumenti (-n, -x), obrazac.

NCP koji čita linije sa standardnog ulaza do markera kraja i štampa sve linije koje sadrže obrazac(sem ako se među
argumentima komandne linije ne nalazi opcija -x). Ukoliko se među opcionim argumentima nalazi -n ispisuje redni
broj linije ispred sadržaja linije. Predvideti mogućnost pojavljivanja oba opciona argumenta u formi -nx, -xn.
Pretpostaviti da ukupan broj linija je strogo manji od LONG_MAX.

Test primer 1: ispisati sve linije teksta sa ulaza koje ne sadrže (opcija: -x) nisku HTML. Uz sadrzaj ispisati i
redne brojeve linija. (opcija -n)

Test primer 2: isto kao primer 1, ali ilustruje prisustvo i kombinaciju oba opciona argumenta
Test primer 3: poziv sa nekorektnom opcijom -z koja je zadata kao argument komandne linije

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXLEN 1000 /*max duzina linije */

/*ucitava liniju limitirane duzine i vraca njenu duzinu */


int getline( char line[], int lim);

main(int argc, char *argv[])


{
char line [MAXLEN] ; /*tekuca linija */
long rednibr=0; /*numeracija linija pod pretpostavkom da je tip long dovoljan */
int znak; /*opcija iz poziva */
int i, j; /*brojaci u petljama i indeksi */
int except=0; /*indikator nailaska na opciju "izuzev" */
int number=0; /*zahtev za numeraciju */
int found=0; /*rezultat koji se vraca okruzenju */

/*prosledjivanje argumenata komandne linije */


for (i=1; i< argc && argv[i][0] == '-' ; i++)
/*prosledjivanje opcija za numeraciju ili "izuzev "*/
for (j=1; znak=argv[i][j]; j++)
switch(znak)
{
/*"izuzev" opcija -x*/
case 'x' : except=1;
break;
/* opcija numeracije -n*/
case 'n' : number=1;
break;
default: printf("Pogresna opcija: %c\n", znak);
exit(1);

/*ucitavanje linija sa standardnog ulaza do markera kraja EOF*/


while (getline(line,MAXLEN) > 0)
{
rednibr++;
/*zavisno od pokazivaca na prvo pojavljivanje *argv u line i vrednosti opcije "izuzev" stampaju se
linije koje sadrze pattern ili ne */
if ( (strstr(line, *argv) != NULL) != except )
{
if (number) printf("%ld: ", rednibr); /*ispisu linije neka prethodi numeracija, ako je tako zahtevano u
komandnoj liniji */
printf("%s", line); /*samo ispis sadrzaja linije */
}
}
return found;
}

/* getline: ucitava liniju i vraca njenu duzinu */


int getline( char line[], int granica)
{int znak, indeks;
for( indeks=0;indeks<granica-1 && (znak=getchar())!=EOF && znak!='\n'; ++indeks)
line[indeks]=znak;
if( znak=='\n' ) line[indeks++]=znak;
line[indeks]='\0';
return indeks;
}

5. Napisati C program koji ce ispisati argumente komandne linije. Predvideti mogucnost ispisa:
a) argumenata komandne linije u novom redu ako je zadata opcija –n u komandnoj liniji
b) argumenata komandne linije sa tabom ako je zadata opcija –t u komandnoj liniji
c) argumenata komandne linije sa navodnicima ako je zadata opcija –q u komandnoj liniji

/*ispisati argumente komandne linije uz opcije: [-n| -t| -q] */


#include <stdlib.h>
#include <stdio.h>

main(int argc, char *argv[])


{ char znak; /*znak iz komandne linije koji ucestvuje u testu opcionih argumenata */
char ispisFormat[4]=""; /*za sada prazna niska ispisnog formata, ciji sadrzaj zavisi od priustva opcionih
argumenata */
int i, j; /*brojaci u petljama i indeksi */
int start=0; /*signal pojave dvostrukog navodnika ispred parametara komandne linije */
int uNovomRedu=0; /*signalizacija pojave opcije -n */
int saNavodnicima=0; /*signalizacija pojave opcije -q */
int saTabom=0; /*signalizacija pojave opcije -t */

/*pretraga flegova -n, -q, -t u komandnoj liniji - videti slican zadatak - zadatak 51*/

/*prosledjivanje argumenata komandne linije */


while (--argc>0 && (*++argv)[0]=='-' )
/*prosledjivanje opcija -n, -q, -t*/
while (znak=*++argv[0] )
switch (znak )
{ case 'n': uNovomRedu=1; break;
case 'q': saNavodnicima=1; start=1; break;
case 't': saTabom=1; break;
default : printf(" Nekorektna opcija %c u komandi %s\n\n",znak, argv[0]);
printf(" Usage: %s [-n -q -t ] strings\n\n",argv[0]);
exit(EXIT_FAILURE);
}

/*popunjavanje niske ispisFormat obracajuci paznju na redosled dodela ,jer ce se ispisFormat


"ispisivati" izmedju svaka dva argumenta komandne linije */
j=0;
if (saNavodnicima) ispisFormat[j++]='\"' ;
if (saTabom) ispisFormat[j++]='\t' ;
if (uNovomRedu) ispisFormat[j++]='\n' ;
/*okoncavanje niske , ako je uopste menjana */
if (j) ispisFormat[j]='\0';

/*ispis u zeljenom obliku,pri cemu deo petlje zaduzen inicijalizaciju je prazan jer je vazno pristupiti tekucoj nisci
*argv.
Uociti da argc se smanjuje u svakoj iteraciji */ */
for(; argc>0; argc--, argv++)
printf("%s%s%s", start? "\"" : "" , *argv, ispisFormat );
printf("\n");
return 0;
}

6. /*jednostavnija igra vesanja */

U datoteci rec.txt čuva se sadržaj reči koju pogađa korisnik. Pretpostaviti da reč se sastoji isključivo od malih slova
(do 20 karaktera). NCP koji od strane korisnika učitava jedno po jedno slovo koje unosi korisnik pogađajući reč. Pri
učitavanju svakog slova, program treba da ispiše ona slova u reči koja su do tada pogođena. Na mestima nepogođenih
slova treba da stoje zvezdice (*). Predvideti da korisnik može da unese nešto što nije slovo u kom slučaju program i
ne mora da mu ispiše trenutni status pogođenih slova (jer se ništa nije promenilo). Predvideti i mogućnost da se
korisniku uvaži unos velikog slova, tj. tretirati ga kao odgovarajuće malo slovo. Ispisati broj pokušaja nakon
pogađanja reči. Jednostavnosti radi, pretpostaviti da izvršna verzija programa se nalazi u istom direktorijumu gde je i
ulazna datoteka rec.txt.

a
*****
e
*e***
O
*e**o
2
5
h
he**o
l
hello
Imali ste ukupno pokusaja: 7

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

main( )
{
FILE *f; /*pristup proizvoljnoj datoteci, pokazivac na strukturu FILE */
char rec[21]; /*rec koja se pogadja */
int duzina; /*duzina reci */
char slovo; /*tekuce slovo pri pogadjanju */
char *ispis; /*rec koja ce se ispisivati tokom pogadjanja stavljajuci * na mesta nepogodjenih slova*/
int pogodjeni; /*broj trenutno pogodjenih slova*/
int pokusaji; /*broj pokusaja; pretpostavka da je tip int dovoljan */
int i; /*brojac u petljama */

f=fopen("rec.txt","r"); //pokusaj otvaranja datoteke za citanje


if (f==NULL) {printf("\nNekorektno otvaranje datoteke\n"); exit(1); }
fscanf(f, "%s",rec); //ucitavanje jedne reci iz datoteke rec.txt, uspesno otvorene sa f=fopen(...)

/*odrediti duzinu reci koja se pogadja */


duzina=strlen(rec);
/*alokacija za rec koja ce se ispisivati */
if ( ( ispis=(char *) malloc ( (duzina+1) * sizeof(char ) ) ) == NULL )
{ printf("Nema u memoriji dovoljno mesta za malloc\n");
exit (EXIT_FAILURE);
}
/*inicijalizacija na znak zvezdica */
for (i=0; i<duzina; i++) ispis [i]='*' ;
ispis[i]='\0';

for(pogodjeni=0,pokusaji=0; pogodjeni <duzina; )


{
/*Ucitava se sledeci karakter. Ako karakter nije slovo, onda se nastavlja sa sledecom iteracijom u ciklusu */
slovo=getchar();
if (slovo =='\n') continue;
pokusaji ++;
if ( ! isalpha(slovo ) ) continue;

/*ako je ucitano veliko slovo - pretvoriti ga u njemu odgovarajuce malo slovo */


if ( isupper(slovo) ) slovo=tolower(slovo) ;

/*odredjivanje da li se slovo pojavljuje u reci: ako se pojavljuje i ukoliko ranije nije pogodjeno,onda ga ukljuciti
kao pogodjeno slovo u ispis i uvecati broj pogodjenih */
for (i=0; i< duzina; i++ )
if (rec[i]==slovo && ispis[i] =='*')
{ ispis[i]=slovo;
pogodjeni ++;
}

/*stampanje tekuceg stanja pogadjanja */


printf("%s\n",ispis);
}

/*oslobadjanje zauzete memorije */


free(ispis);

/*stampa se broj pokusaja */


printf("Imali ste ukupno pokusaja: %d\n", pokusaji );
fclose(f); //zatvaranje datoteke otvorene sa f=fopen(..)

exit (EXIT_SUCCESS);

7. NCP koji će sabrati dva broja koji se zadaju kao dva parametra komandne linije

/*u ovom zadatku broj u dekadnom zapisu se predstavlja niskom cifara,


gde prvo idu cifre manje tezine (sto je suprotan redosled od onoga koji je unet komandnom linijom).
Izabran je redosled cifara koji je vise odgovarao prilikom racunanja. */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define znak(cifra) ((cifra) +'0')
#define cifra(x) ((x)-'0')
void saberi(char *a1, int n, char *a2, int m, char *s, int *ns); /*a1+a2->s */
/*Kako u ovom zadatku koristimo nisku cifara , u potprogramima nisu bili nuzni
n,m, ali ih prenosimo da bi kod bio jasniji i da bi se mogao primeniti i ako
se radi sa npr. (int *) , umesto (char *) */
char* reverse( char s[] ) ;
int main(int argc, char *argv[])
{
int n=strlen(argv[1]); /*br.cifra prvog "broja" */
int m=strlen(argv[2]); /*br.cifara drugog "broja" */
int nzbir; /*br cifara zbira */
char *zbir; /*zbir oba broja */

/*inicijalizacije */
nzbir= (n>m ? n : m) +1; /*nzbir=max(n,m)+1 */
if(argc !=3)
{ fprintf(stderr,"\nNekorektan broj argumenata komandne linije u pozivu programa\n");
exit(1);
}
/*sabiranje */
zbir=(char *)malloc(nzbir*sizeof(char) );
saberi( reverse(argv[1]) ,n, reverse(argv[2]),m,zbir,&nzbir);
printf("\n%s+%s= %s\n\n", reverse(argv[1]),reverse(argv[2]), reverse(zbir));
free(zbir);
return 0;
}

void saberi(char *a1, int n, char *a2, int m, char *s, int *ns)
{
int prenos; /*prenos u susedni razred cifara, a koji je nastao
pri sabiranju cifri oba broja tekuceg razreda */
int c; /*rezultat sabiranja tekuce cifre prvog broja i tekuce cifre drugog broja*/
int i; /*brojac u petlji */
prenos=0;
/*sabiranje velikih brojeva se odvija implementacijom algoritma naucenom u mladjim razredima osnovne skole */
/*Sabiraju se cifre oba broja iz tekuceg razreda, pocev od razreda jedinica ,ka razredima vece tezine. */
/*Vodi se racuna o eventualnom nastalom prenosu u sledeci razred cifara, /*
/*kao i da ako je neki od brojeva "kraci", postavljaju mu se zamisljene nule kao cifre tekuceg razreda .*/
/*Te zamisljene nule su vodece nule, i zato ne uticu na izmenu vrednosti broja */

for(i=0; i<*ns; ++i) {


c= (i<n ? cifra(a1[i]) : 0) + (i<m ? cifra(a2[i]) : 0) + prenos;
s[i]= znak(c % 10) ;
/*formira se cifra rezultata ,kao vrednost arapske cifre u masinskom setu znakova */
prenos= c < 10 ? 0 : 1; /* prenos=c/10; */
} //kraj for petlje

if(prenos > 0) {
s[*ns]=znak(prenos);
*ns=*ns+1;
}
s[*ns]='\0'; /*zbog rada sa niskom cifara */
} //kraj potprograma

char* reverse( char s[] )


{
int indeks,br; /* brojacke promenljive */
char Temp;/* posrednik u razmeni dva karaktera sa iz leve i desne polovine stringa */
br=strlen(s)-1;
for( indeks=0; indeks< br; indeks++, br-- )
{ Temp=s[indeks]; s[indeks]=s[br]; s[br]=Temp; }
return s;
}

8. NCP koji će pomnožiti dva broja koji se zadaju kao dva parametra komandne linije
/*vaze napomene iz 5. zadatka */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define znak(cifra) ((cifra) +'0')
#define cifra(x) ((x)-'0')
void mnozi(char *a1, int n1, char *a2, int n2, char *p, int *np); /*a1 * a2 -> p*/
char* reverse( char s[] );
int main(int argc, char *argv[])
{
int n=strlen(argv[1]); /*br.cifra prvog "broja" */
int m=strlen(argv[2]); /*br.cifara drugog "broja" */
int nproizvod; /*br.cifara proizvoda */
char *proizvod; /*proizvod oba broja */

/*inicijalizacije */
nproizvod=n+m;
if(argc !=3)
{ fprintf(stderr,"\nNekorektan broj argumenata komandne linije u pozivu programa\n");
exit(1);
}
/*mnozenje */
proizvod=(char *)malloc(nproizvod*sizeof(char)) ;
mnozi(reverse(argv[1]),n,reverse(argv[2]),m,proizvod,&nproizvod);
printf("\n%s\n*\n%s=\n%s\n", reverse(argv[1]),reverse(argv[2]), reverse(proizvod));
free(proizvod);
return 0;
}

char* reverse( char s[] )


{
int indeks,br; /* brojacke promenljive */
char Temp;/* posrednik u razmeni dva karaktera sa iz leve i desne polovine stringa */
br=strlen(s)-1;
for( indeks=0; indeks< br; indeks++, br-- )
{ Temp=s[indeks]; s[indeks]=s[br]; s[br]=Temp; }
return s;
}

void mnozi(char *a1, int n1, char *a2, int n2, char *p, int *np)
{
int prenos; /*prenos u susedni razred i+j+1;voditi racuna kada j==n2*/
int c; /*rezultat sabiranja proizvoda cifara koje ucestvuju u forimranju (i+j).te cifre rezultata */
int i, j; /*brojaci u petljama */
/*inicijalizacije */
for(j=0; j<*np; ++j)
p[j]=znak(0);
p[j]='\0';
/*mnozenje: (i+j).-ta cifra rezultata je jednaka sumi a1[i]*a2[j] */
for(i=0; i<n1; ++i) {
prenos=0; /*resetovanje prenosa pre formiranja (i+j)-te cifre rezultata */
for(j=0; j<n2; ++j) {
c= cifra(a1[i]) * cifra(a2[j]) + cifra(p[i+j]) + prenos;
p[i+j]= znak(c%10);
prenos= c/10;
} //unutrasnji for
p[i+n2]= znak(prenos);
} //spoljasnji for

*np= prenos>0 ? n1+n2 : n1+n2-1;


p[*np]='\0';
} //kraj potprograma

You might also like