Vezbe iz Osnova programiranja


 

46. NCP koji sa standardnog ulaza učitava raspored 8 topova na šahovskoj tabli. Raspored se učitava u formi 8 linija sa po 8 brojeva po liniji. Ako na datom polu nema topa, učitava se 0, a inače 1. Program mora da ispita validnost unetog rasporeda ( da li su učitani brojevi ili 0 ili 1, da li ima 8 topova) i ispita da li se u datom rasporedu dva topa tuku.

matrica topova


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

main()
{ int tabla[8][8];  /*matrica nula i jedinica  cuva raspored  8  topova na  tabli */
   int suma;          /* pamti se suma reda/kolone kao test osobina iz zahteva zadatka */
    int i,j;               /*brojaci u petljama */

/*ucitavanje podataka o rasporedu topova  uz sumiranje broja topova i u slucaju greske
   stampa se odgovarajuca poruka i okoncava programa */
suma=0;
 for (i=0; i<8; i++ )
   for (j=0; j<8; j++)
     {  scanf("%d", &tabla[i][j]);

          /*test korektnosti ulaza */
          if (tabla[i][j] !=0 && tabla[i][j] !=1 )
             { printf ("\nNekorektni  ulazni podaci o rasporedu topova\n");
                 exit(EXIT_FAILURE);
             }
          suma=suma + tabla[i][j];
     }
 

/*greska je ako je broj topova na tabli razlicit od 8 */
if (suma !=8)
  { printf ("\nNekorektni  ulazni podaci o broju topova\n");
                 exit(EXIT_FAILURE);
    }

/*proveravanje da li se dva topa nalaze u istom redu , tj. da li je suma
   clanova nekog reda  veca od 1 */
for(i=0;i<8;i++)
  {
       suma=0;
       for (j=0;j<8;j++)  suma+=tabla[i][j];
       if (suma >1 )
        { printf ("\nTopovi se tuku\n");
                 exit(EXIT_SUCCESS);
         }
    }
 

/*proveravanje da li se dva topa nalaze u istoj koloni , tj. da li je suma
   clanova neke kolone    veca od 1 */
for(j=0;j<8;j++)
  {
       suma=0;
       for (i=0;i<8;i++)  suma+=tabla[i][j];
       if (suma >1 )
        { printf ("\nTopovi se tuku\n");
                 exit(EXIT_SUCCESS);
         }
    }
 

/*inace se topovi ne tuku */
printf ("\nTopovi se ne tuku\n");
exit(EXIT_SUCCESS);

}
 

47. NCP koji sa standardnog ulaza unosi broj n (n <=30) i niz od n celih brojeva. Ispisati na standardni izlaz niz sortiran metodom quick sort.   

uzorak za sortiranje qsort-om

qsort I
44 5512 4294 18667 => 42 5512 4494 18667

qsort I for ciklus
42 55 12 4494 18667 => 42 1255 4494 18667
42 12 55 4494 18 667 => 42 1218 4494 55667
42 12 18 4494 55 667 => 42 1218 694 554467

qsort I van for ciklusa
42 12 18 694 55 4467 => 6 1218 4294 554467

 

qsort 2
6 12 18 4294 55 4467 => 12 618 4294 554467
12 6 18 4294 55 4467 => 6 1218 4294 554467

 

qsort II 1
6 12 18 4294 55 4467 => 6 1218 4255 944467

qsort II 1 for ciklus
6 12 18 4255 94 4467 => 6 1218 4255 449467

qsort II 1 van for ciklusa
6 12 18 4255 44 9467 => 6 1218 4244 559467

 

qsort III van for ciklusa
6 12 18 4244 55 94 67 => 6 1218 4244 556794

 


#include <stdio.h>
#define MAX 30             /*max broj clanova niza */
/* swap: razmenjuje clanove niza */
void swap( int niz[], register int prvi, register int drugi );
/*sortira niz[levi]...niz[desni]  u neopadajucem  poretku*/
void qqsort( int niz[], int  levi,int desni);

/* glavni program */
main()
{
int n;           /*broj clanova niza */
int a[MAX];            /*niz koji se sortira */
int indeks;           /*brojac u petlji */

/*unos broja clanova niza */
do
 { printf("Unesite broj elemenata niza: "); scanf("%d",&n);
} while (n <1 || n >MAX) ;

/*unos clanova niza */
 for( indeks=0; indeks<n; indeks++)
 {   printf("\n%d. clan niza je: ", indeks+1);
      scanf("%d",&a[indeks]);
}

/*sortiranje algoritmom QuickSort */
qqsort(a,0,n-1);

/*stampanje sortiranog niza */
for( indeks=0; indeks<n; indeks++)
  printf("%d\t", a[indeks]);
printf("\n");
return 0;
}

/* swap: razmenjuje clanove niza */
void swap( int niz[], register int prvi, register int drugi )
{
 register int temp;
 temp = niz[prvi];
 niz[prvi] = niz[drugi];
 niz[drugi] = temp;
}
 

O SORTIRANjU

/* qqsort: sortira clanove sa pozicija od levi do desni u neopadajuci poredak */
void qqsort( int niz[], int levi, int desni )
{
  int i ;   /*brojac u petlji */
  int  last;    /*indeks clana -razdvajanje   */

  if( levi>=desni )  return;  /*kad u nizu ostane manje od dva kandidata,ne preduzimati nista */
 swap( niz, levi, (levi+desni)/2 );  /*trampa clana iz prvog podskupa i clana za razlaganje */
  last = levi;
  for( i=levi+1; i<=desni; i++)           /*ostatak */
  if( niz[i]<niz[levi] )
   swap( niz, ++last, i );
    swap( niz, levi, last );
    qqsort( niz, levi, last-1 );          /*sortiranje prvog podniza */
   qqsort( niz, last+1, desni );       /*sortiranje drugog podniza*/
}
 

48. Šta je rezultat rada sledećeg programa?

prikaz adrese i sadrzaja u memoriji


/* broj karaktera u nizu */
#define ARRAY_SIZE 10
 char array[ARRAY_SIZE] = "012345678";    /* niska znakova*/
main()
{
   int index;   /* brojac u petlji  */

  /* stampanje clanova niza prema zahtevu */
  for (index = 0; index < ARRAY_SIZE; index++)
     {
        printf( "&array[index]=0x%x (array+index)=0x%x array[index]=0x%x\n", &array[index], (array+index), array[index]);
     }
 return (0);
}
 

49. Šta je rezultat rada sledećeg programa?

pointer na pointer


#include <stdio.h>
char * c[]={"html","\\a","HEAD","a\thref","\\body"};
char **cp[]={c+3,c+4,c,c+1,c+2};
char ***cpp=cp;
main()
{   printf("1 %s\n", **++cpp);
    printf("2 %s\n", **++cpp+1);
   printf("3 %s\n", *((--cpp)[-1]) );
    printf("4 %s\n", **cpp+1);
    printf("5 %s\n", **++cpp);
    return 0;
 }
 

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

argumenti 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] );
}
 

51.   /* find_str     [-n|-x]  pattern */

Arhumenti 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.

 


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)

nalaz uzorka u linijama teksta


Primer 2: isto kao primer 1, ali ilustruje prisustvo i kombinaciju oba opciona argumenta

nalaz uzorka u linijama teksta


Primer 3: poziv sa nekorektnom opcijom -z koja je zadata kao argument komandne linije

nalaz uzorka u linijama teksta


 #include <stdio.h>
#include <string.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*/
           case 'x' :  except=1;
                           break;
            /* opcija numeracije */
             case 'n' : number=1;
                             break;
             default:  printf("Pogresna opcija: %c\n", znak);
                            argc=0;
                            found=-1;
                            break;
          }
 

        if (argc != 1) {  printf("Pogresan format poziva! \n");
                                   if (found != -1) found=1; }
        else
            /*unos linija do markera kraja */
     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;
}
 
 

52.   /*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;
}

53.       /*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);

}

54. 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[] ) ;
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; 
} 
55. NCP koji će pomnožiti dva broja koji se zadaju kao dva parametra komandne linije
/*vaze napomene iz 54. 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[] ); 
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

56.         /*SORT  leksikografski - za vežbu */
NCP koji učitava linije ulaznog teksta limitirane dužine do markera EOF i ispisuje ih sortirane u leksikografskom poretku. Smatrati da broj linije nije veći od 1000.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXLINES 1000  /*ogranicenje na broj linija za sortiranje */
 

/*ucitavanje ulaznog reda limitirane duzine uz vracanje (ne)dozvoljenog broja linije */
int readlines( char *linije[], int n);
/*ispis linija na izlaz */
void writelines( char *linije[], int n);
/*sortiranje linija */
void qqsort( char *linije[], int donja, int gornja);
/*ispis izlaznog reda */
void ispis( char* linije[], int i);
/*razmena dve linije */
void swap(char *niz[], int i , int j);
/*ucitavanje linije i vracanje duzine */
int getline(char *,int);

char *linije[MAXLINES];   /*pokazivaci na linije teksta sa ulaza . Sta ako je niz linija lokalni u main-u ?*/
main()
{
  int n;         /* broj procitanih ulaznih redova */
      puts("\n\nUnesite linije teksta za sortiranje.");
     if( (n = readlines(linije, MAXLINES)) >= 0 )
      {
  qqsort( linije, 0, n-1);
  writelines(linije, n);
   return 0;
  }
    else
    {
     printf("Greska: ulaz predugacak za sortiranje\n");
     return 1;
 }
}

#define MAXLEN 81 /*max duzina ma koje linije*/
int readlines( char *linije[], int maxlines)     /* ucitavanje ulaznog reda */
{
 int duz, n;
     char *p, line[MAXLEN]; // line je pomocni bafer
     n = 0;
     while((duz = getline(line, MAXLEN)) > 0 )
  if( n >= maxlines || (p = (char *) malloc(duz)) == NULL)
       return -1;   /*preobiman ulaz*/
   else
  {
       line[duz - 1] = '\0';      /* izbaci novi red */
       strcpy(p, line);
       linije[n++] = p;
 }
 return n;
}

/* unos linije i odredjivanje duzine  (sa '\0') */
int getline( char s[], int lim )
{   int c, i;
 i = 0;
    while( --lim > 0 && (c = getchar()) != EOF && ( c != '\n' ) )
        s[i++] = c;

    if( c == '\n' )
 s[i++] = c;
     s[i] = '\0';
    return i;
}

/* ispis linija teksta */
void writelines(char *linije[], int n )
{
   int i=0;
   if (n) puts("sortirane linije\n");
   else puts("nije bilo linija na ulazu!");
   for(; i < n; i++) ispis(linije,i);

}

/* ispis izlaznog reda */
void ispis( char* linije[], int i)
{
 /* simulacija printf("%s\n", linije[i]);  */
   int k;
     for( k = 0; k < strlen(linije[i]); k++)
  putchar(linije[i][k]);   // ispis znak po znak !!!
    printf("\n");
}

// quick sort !!!
void qqsort( char *niz[], int donja, int gornja)
{
 int i, pom;
 if(donja >= gornja) return; /*ne preduzimati nista u situaciji kada ostane manje od dva elementa */
   swap( niz, donja, (donja+gornja)/2);
   pom = donja;
   for(i = donja + 1; i <= gornja; i++)
       if (strcmp(niz[i], niz[donja]) < 0)     // poredjenje !
      swap(niz, ++pom, i);
   swap( niz, donja, pom);
   qqsort( niz, donja, pom-1);
   qqsort( niz, pom+1, gornja);
}

void swap(char *niz[], int i, int j)
{  char *pom;
   pom = niz[i];
   niz[i] = niz[j];
   niz[j] = pom;
}
 

57. NCP koji iz datoteke ulaz.txt ucitava dimenizju niza, a potom i niz celih brojeva (ciji broj nije unapred poznat), a na standardni izlaz ispisuje dimenziju podniza koji se sastoji samo od pozitivnih brojeva. Zadatak realizovati upotrebom dinamickog niza



#include <stdio.h> 
#include <stdlib.h>
#define GRESKA_DODELA  0 /*status prve poruke o gresci*/
#define GRESKA_PROMENA 1 /*status II poruke o gresci */
#define GRESKA_DATOTEKA 2 /*status III poruke o gresci */

char *poruke[]=
{  "\nNesupesna dodela memorije\n", "\nNeuspesna promena dinamicki dodeljene memorije\n",
    "\nGreska pri otvaranju datoteke ulaz.txt\n"};

void ucitavanje(int a[], FILE *f); //ucitavanje niza iz datoteke
int sazima_niz(int a[], int n); //eliminacija clanova niza koji nisu pozitivni	              
void stampa_niz(int a[], int n);
void greska (int satus); /*ispis poruka o gresci */

main( ) 
{  FILE *f;
    int *a, n; //niz iz datoteke i broj clanova
    int n2; //dimenizija sazetog niza
    
	
	f=fopen("ulaz.txt", "r");
	if (f==NULL) greska(GRESKA_DATOTEKA);
	fscanf(f, "%d", &n);
	
	a=(int *)malloc(n* sizeof(int));
    if (a==NULL)  greska(GRESKA_DODELA);
    ucitavanje(a,f);
	n2=sazima_niz(a,n);

	//ako se promenila dimenzija niza n, onda se 
	//vrsi (re)alokacija za niz manje dimenzije n2
		if (n2<n)
			if( (a=realloc(a, n2*sizeof(int))) ==NULL) greska(GRESKA_PROMENA);

	stampa_niz(a,n2);

	//oslobadja se memorija za sazeti niz
	free(a);

	fclose(f);

	return 0; 
} 


void ucitavanje(int a[], FILE *f)
{
	int i=0;
	/*citanje brojeve iz datoteke, fscanf vraca broj uspesnih
	ucitavanja ili EOF pri nailasku na kraj datoteke */
	while (fscanf(f, "%d", &a[i++])) 
	   if (feof(f)) break; /*prekida se citanje nailaskom na EOF */
}


int sazima_niz(int a[], int n)
{  int i;  //brojac
   int *ptr1, *ptr2; /*pokazivac ptr1 pratice adrese svih elemenata polaznog niza,
                    pokazivac ptr2 ce se koristiti za formiranje novog niza*/
   
ptr1=ptr2=a;

    for(i=0; i<n; i++)
	{ if(*ptr1>0)    /*ako je tekuci clan niza pozitivan */
	    { *ptr2=*ptr1;
	       ptr2++;          /*ulazi u sastav novog niza*/
	    }
       ptr1++; //prelazi se na poziciju sledeceg clana polaznog niza
	}

	return (ptr2-a); /*dobija se broj clanova novog niza */
}

void stampa_niz(int a[], int n)
{ int i;
  printf("\Novi niz\n");
  for(i=0; i<n; i++)  printf("%d ", a[i]);
  printf("\n\n");
}

void greska(int status)
{
	  puts(poruke[status]);
	  exit(1);
}




58. NCP koji sa standardnog ulaza učitava kvadratnu matricu kojom je predstavljena neka relacija i ispisuje da li relacija je refleksivna, simetrična, tranzitivna. Dakle, elementi matrice su 0 i 1 (vrednost 0 u i-tom redu i j-toj koloni označava da i-ti element skupa nije u relaciji sa j-tim elementom). U prvoj liniji standardnog ulaza nalazi se dimenzija matrice n, a zatim se učitava n redova sa po n elemenata. Elementi matrice su razdvojeni blanko znakom. Dimenzija matrice jeste celobrojna, ali nije unapred poznata.
#include <stdio.h>
#include <stdlib.h>

/* Funkcija ucitaj_matricu() ucitava matricu u zadatom formatu sa standardnog  ulaza. Argumenti funkcije su:
  pn - pokazivac na lokaciju koja ce sadrzati dimenziju matrice
  pA - pokazivac na lokaciju koja ce opisivati matricu, pri cemu je matrica
        predstavljena poljem pokazivaca na redove matrice (za element matrice
        se koristi char tip zato sto element moze imati samo vrednosti 0 ili 1*/
void ucitaj_matricu (int *pn, char ***pA);

/* Funkcija proveri_refleksivnost() proverava refleksivnost relacije predstavljene matricom. Argumenti funkcije su:
  n - dimenzija matrice
  A - matrica predstavljena poljem pokazivaca
Funkcija vraca 1 ukoliko je relacija refleksivna, odn. 0 ako nije. */
int proveri_refleksivnost (int, char **);

/* Funkcija proveri_simetricnost() proverava simetricnost relacije predstavljene matricom. Argumenti funkcije su:
  n - dimenzija matrice
  A - matrica predstavljena poljem pokazivaca
Funkcija vraca 1 ukoliko je relacija simetricna, odn. 0 ako nije. */
int proveri_simetricnost (int, char **);

/* Funkcija proveri_tranzitivnost() proverava tranzitivnost relacije predstavljene matricom. Argumenti funkcije su:
  n - dimenzija matrice
  A - matrica predstavljena poljem pokazivaca
Funkcija vraca 1 ukoliko je relacija tranzitivna, odn. 0 ako nije. */
int proveri_tranzitivnost (int, char **);
 

main ()
{
int n;   /* Dimenzija matrice. */
char **A;   /* Matrica predstavljena poljem pokazivaca. */
int i;   /* Brojac u petlji. */

/* Ucitavanje  matrice */
  printf ("Uneti matricu u zadatom formatu:\n");
  ucitaj_matricu (&n, &A);

/* Provera relacija predstavljenih matricom. Ako je svaka od njih zadovoljena, ispisuje se odgovarajuca poruka. */
  if (proveri_refleksivnost (n, A))
    printf ("Matrica je refleksivna\n");
  if (proveri_simetricnost (n, A))
    printf ("Matrica je simetricna\n");
  if (proveri_tranzitivnost (n, A))
    printf ("Matrica je tranzitivna\n");

/* Oslobadjanje memorije koju je zauzimala matrica. */
  for (i = 0; i < n; i++)
    free (A[i]);
  free (A);

  /* Zavrsava se program. */
  exit (EXIT_SUCCESS);
}

void  ucitaj_matricu (int *pn, char ***pA)
{
  int clan;   /* Tekuci element matrice koji se ucitava. */
  int i, j;   /* Brojaci u petljama. */

  /* Ucitava se dimenzija matrice. */
  scanf ("%d", pn);

  /* Alocira se memorija za polje pokazivaca na redove matrice, kao i za      same redove. */
  *pA = (char **) malloc (*pn * sizeof (char *));
  for (i = 0; i < *pn; i++)
    (*pA)[i] = (char *) malloc (*pn * sizeof (char));

  /* Ucitava se jedan po jedan element matrice. Ucitavanje se vrsi u int  promenljivu, a potom se vrednost te promenljive prepisuje u element   matrice koji je char tipa.       Ovako je jednostavnije, jer se ucitavanje vrsi  formatirano (pomocu scanf() funkcije, a elementi matrice mogu biti  samo 0 i 1 tako da je za njihovo predstavljanje upotrebljen char tip da  se ne bi rasipala memorija. Vredi razmisliti o daljem poboljsanju efikasnosti  tako sto bi se elementi matrice smestali u pojedinacne bitove. */
  for (i = 0; i < *pn; i++)
    for (j = 0; j < *pn; j++)
      {
 scanf ("%d", &clan);
 (*pA)[i][j] = (char) clan;
      }
}

int proveri_refleksivnost (int n, char **A)
{
  int i; /* Brojac u petlji. */
/* Proverava se refleksivnost i iz petlje se izlazi cim se ustanovi da relacija nije zadovoljena. */
  for (i = 0; i < n; i++)
    if (!A[i][i])
      return 0;

  /* Ako se proslo kroz citavu petlju, relacija je zadovoljena. */
  return 1;
}

int proveri_simetricnost (int n, char **A)
{
  int i, j;   /* Brojaci u petljama. */

  /* Proverava se simetricnost i iz petlji se izlazi cim se ustanovi da relacija nije zadovoljena. Pri proveri se prelazi samo deo matrice
     iznad gornje dijagonale, jer je tako dovoljno. Uociti da pri ispitivanju  simetricnosti elementi moraju biti razliciti. */
  for (i = 0; i < n - 1; i++)
    for (j = i + 1; j < n; j++)
      if (A[i][j] != A[j][i])
 return 0;

  /* Ako se proslo kroz obe petlje, relacija je zadovoljena. */
  return 1;
}

int proveri_tranzitivnost (int n, char **A)
{
  int i, j, k;   /* Brojaci u petljama. */

  /* Proverava se tranzitivnosti i iz petlji se izlazi cim se ustanovi da relacija nije zadovoljena. Uociti da pri ispitivanju tranzitivnosti
     elementi moraju biti razliciti. Tranzitivnost se moze matematicki  interpretirati i na nesto drugaciji nacin*/
  for (i = 0; i < n; i++)
    for (j = 0; j < n; j++)
      if (i != j)
 for (k = 0; k < n; k++)
   if (k != i && k != j)
     if (A[i][k] && A[k][j] && !A[i][j])
       return 0;

  /* Ako se proslo kroz sve tri petlje, relacija je zadovoljena. */
  return 1;
}

59. NCP koji sa standardnog ulaza učitava kvadratnu matricu čiji elementi su celi brojevi i ispisuje da li matrica je ortogonalna. U prvoj liniji standardnog ulaza nalazi se dimenzija matrice n, a zatim se učitava n redova sa po n elemenata. Elementi matrice su razdvojeni blanko znakom. Dimenzija matrice jeste celobrojna, ali nije unapred poznata. Može se pretpostaviti da sve linije sem eventualno prve su u ispravnom formatu.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
void ucitaj_matricu (unsigned *dim, int ***matrica);
/* ucitavanje  matrice  u formulisanom formatu sa standardnog  ulaza
  dim <-> pokazivac na lokaciju koja sadrzi dimenziju matrice
  matrica< -> pokazivac na lokaciju koja opisuje  matricu, pri cemu matrica se
 predstavlja poljem pokazivaca na vrste matrice koje sadrze int  clanove*/

int ortogonalna( int **matrica , int dim);
/*funkcija ortogonalna proverava ortogonalnost matrice.
 matrica - pokazivac na lokaciju koja ce opisivati matricu */
 

/* glavna funkcija */
main ()
{
  int **a;   /* matrica kao polje pokazivaca. */
  unsigned Dim;         /* dimenzija matrice. */
  int i;   /* lokalni brojac  */

  /* ucitavanje  matrice */
  printf ("Uneti matricu u opisanom obliku:\n");
  ucitaj_matricu (&Dim, &a);

  /* Proverava se ortogonalnost matrice i ispisuje se odgovarajuca poruka. */
  if (ortogonalna(a,Dim))
    printf ("Matrica je ortogonalna\n");
 else printf ("Matrica nije ortogonalna\n");
    /* Oslobadja se memorija koju je zauzimala matrica. */
  for (i = 0; i < Dim; i++)
    free (a[i]);
  free (a);

  return (EXIT_SUCCESS);
}

void ucitaj_matricu (unsigned *dim, int  ***matrica)
{
  int pom;  /* element matrice koji se ucitava. */
  int i,j;        /* brojaci  */
  int c;          /*karakter prve linije */
  int preth;      /*indikator nepraznosti prve linije */

/* ucitavanje  dimenzije  matrice. */
for(preth=0,*dim=0;(c=getchar() ) !='\n' ;*dim=*dim*10+(c-'0'),preth=1 )
  {if ( !isdigit(c) )
     { fprintf(stderr,"Nekorektan unos dimenzije"); exit(1); }
  }
if (!preth)
  {fprintf(stderr,"Nekorektan unos dimenzije \n"); exit(1); }

/* alociranje memorija za polje pokazivaca na vrste matrice, a potom i za
 same vrste */
  if  (  (*matrica = (int **) malloc (*dim * sizeof (int *)) ) == NULL)
               fprintf(stderr,"Ne moze da se alocira prostor\n");
  for (i = 0; i < *dim; i++)
    (*matrica)[i] = (int *) malloc (*dim * sizeof (int));

  /* ucitavanje elemenata matrice.      */
  for (i = 0; i < *dim; i++)
    for (j = 0; j < *dim; j++)
      {
 scanf ("%d", &pom);
 (*matrica)[i][j] = pom;
      }
}
 

int ortogonalna( int  **matrica , int   dim)
{
 int i,j,k,pom ,ort=1 ;

for (i=0;i< dim && ort; i++)
  for (j=0;j< dim && ort; j++ )
{ pom=0;

  for (k=0; k< dim; k++)
   /*izracunati clan [i,j] matrice (A)*(AT)   */
   pom+= matrica[i][k] * matrica[j][k];

/*test (van)dijagonalnih clanova proizvoda */
ort= ( (i==j) && (pom==1) ) || ( (i!=j) && (pom==0) );
}
return ort;
}

60.   /*pokazivaci na f-je */
NCP koji ispisuje na standardnom izlazu tri HTML tabele. Svaka tabela ima dve kolone. Prva kolona u sve tri tabele su brojevi od 1..n. U prvoj tabeli druga kolona su kvadrati brojeva od 1..n, a u drugoj tabeli druga kolona su prigušene oscilacije brojeva od 1..n, u trećoj tabeli druga kolona su kubovi brojeva od 1..n. Broj n se unosi sa standardnog ulaza.

#include <stdio.h>
#include <math.h>

/*f-ja koja formulom po argumentu tipa double opisuje prigusene oscilacije */
double priguseneOscila(int );

/*f-ja koja racuna kvadrat argumenta */
double kvadrat(int);

/*f-ja koja racuna kub argumenta */
double kub(int);

/*f-ja koja stampa HTML tabelu sa dve kolone */
void stampati( double (*ptrFunk) (int), int n)
{  int i; //brojac u ciklusu

   /*zaglavlje tabele*/
printf("\n<TABLE><TR><TH>I kolona</TH><TH>II kolona</TH></TR>\n");

for(i=1;i<=n;i++) printf("\n<TR><TD>%d</TD><TD>%lf</TD></TR>", i, (*ptrFunk)(i));
printf("</TABLE>");

}

main( )
{  int n;
    scanf("%d",&n); printf("<HTML>\n<HEAD></HEAD><BODY>\n");
//ispis 1. tabele
    stampati(priguseneOscila,n);
//ispis 2. tabele
    stampati(kvadrat,n);
//ispis 3. tabele
    stampati(kub,n);

printf("\n</BODY></HTML>\n");
    return 0;
}

double priguseneOscila(int x)
{ return exp(- 0.1 * x) * sin(x); }

double kvadrat(int x)
{ return (x)*(x);
}

double kub(int x)
{ return (x)*(x)*(x);
}
 

61.   /*SORT [-n]     K&R*/
NCP koji unosi sa standradnog ulaza ograničeni broj linija ograničene dužine. Ispisati ih na standardni izlaz sortirane u leksikografskom poretku, sem ako se kao argument komandne linije ne proslefi opcija -n koja označava numeričko, a ne leksikografsko sortiranje.

 

K&R resenje sa korisnickom qqsort (uporediti sa zad. 47) resenje sa biblioteckom qqsort (zaglavlje stdlib.h)
#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#define MAXLINES 1000  /*maximum linija koje ce se  sortirati*/ 
char *lineptr[MAXLINES];  /*pokazivaci na linije teksta */ 
#define MAXLEN 80    /*ogranicenje na duzinu linije za ucitavanje */ 
// quick sort !!! 
void qqsort( void *v[], int left, int right, int (*comp) (void *, void * ));
/*razmena sadrzaja dva elementa */ 
void swap(void *v[], int i, int j) ; 
/*poredi niske s1 i s2 numericki prema vrednosti brojeva koje predstavljaju */ 
int numcmp(char *s1,char *s2); 
int readlines( char *lineptr[], int maxlines);     /* ucitavanje ulaznog reda */ 
/* unos linije i odredjivanje duzine */ 
int getline( char s[], int lim ) ; 
/* ispis linija teksta */ 
void writelines(char *lineptr[], int nlines ); 
/* ispis izlaznog reda */ 
void ispis( char *lineptr[], int i); 
  
main(int argc, char *argv[]) 
 { 
  int nlines;         /* broj procitanih ulaznih redova */ 
 int vrsta = 0;   /* vrsta poredjenja:1 ako je numericko*/ 
 // obrada komandne linije 
 if( argc > 1 && strcmp(argv[1],"-n") == 0 ) vrsta=1; 
      //  argv[1] je pokazivac na nisku - mora strcmp 
 if( argc > 2 ) puts("\n\nvisak parametara - ignorisu se!"); 
 /*obrada linija sa ulaza */ 
   if( (nlines = readlines(lineptr, MAXLINES)) >= 0 ) 
      { 
   /*uporediti sa qqsort-om iz 85. */ 
      qqsort( (void **)lineptr, 0, nlines-1, (int (*) (void*,void*) ) (vrsta?numcmp: strcmp));
      writelines(lineptr, nlines); 
      return 0; 
  } 
    else 
    { 
     printf("Greska: ulaz predugacak za sortiranje\n"); 
     return 1; 
 } 
} 
// quick sort !!! 
void qqsort( void *v[], int left, int right, int (*comp) (void *, void * ))
{ int i, last; 
  if(left >= right) return; 
  swap( v, left, (left+right)/2); 
  last = left; 
  for(i = left + 1; i < = right; i++) 
 if( (*comp)(v[i], v[left]) < 0)     // poredjenje ! 
      swap(v, ++last, i); 
  swap( v, left, last); 
  qqsort( v, left, last-1, comp);
  qqsort( v, last+1, right, comp);
} 
void swap(void *v[], int i, int j) 
{  void *temp; 
   temp = v[i]; 
   v[i] = v[j]; 
   v[j] = temp; 
} 
/*poredi niske s1 i s2 numericki prema vrednosti brojeva koje predstavljaju */ 
int numcmp(char *s1,char *s2) 
{ double v1,v2; 
  v1=atof(s1); 
  v2=atof(s2); 
  if (v1 < v2)  return -1; 
  else if (v1 > v2) return 1; 
      else return 0; 
} 
  
int readlines( char *lineptr[], int maxlines)     /* ucitavanje ulaznog reda */ 
{ 
int len ;    /*duzina ucitane linije */ 
int nlines ; /*broj ucitanih linija */ 
char *p;     /*tekuca linija */ 
char line[MAXLEN]; // line je pomocni bafer 
nlines = 0; 
/*ucitavanje linija do markera kraja ili do limita */ 
while((len = getline(line, MAXLEN)) > 0 ) 
   if( nlines >= maxlines || (p = (char *) malloc(len)) == NULL) 
    return -1; 
    else 
 { 
  line[len - 1] = '\0';      /* izbaci novi red */ 
  strcpy(p, line); 
  lineptr[nlines++] = p; 
 } 
 return nlines; 
} 
/* unos linije i odredjivanje duzine  (sa '\0') */ 
int getline( char s[], int lim ) 
{ int c, i; 
  i = 0; 
  while( --lim > 0 && (c = getchar()) != EOF && ( c != '\n' ) ) 
        s[i++] = c; 
  if( c == '\n' )s[i++] = c; 
  s[i] = '\0'; 
  return i; 
} 
/* ispis linija teksta */ 
void writelines(char *lineptr[], int nlines ) 
{ 
   int i=0; 
   if (nlines) puts("sortirane linije\n"); 
   else puts("nije bilo linija na ulazu!"); 
   for(; i < nlines; i++) ispis(lineptr,i); 
} 
/* ispis izlaznog reda */ 
void ispis( char *lineptr[], int i) 
{ 
 /* simulacija printf("%s\n", lineptr[i]);  */ 
   int k; 
     for( k = 0; k < strlen(lineptr[i]); k++) 
  putchar( lineptr[i][k] );   // ispis znak po znak !!! 
    printf("\n"); 
} 
   
#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#define MAXLINES 1000  /*maximum linija koje ce se  sortirati*/ 
char *lineptr[MAXLINES];  /*pokazivaci na linije teksta */ 
#define MAXLEN 80    /*ogranicenje na duzinu linije za ucitavanje */ 
/*razmena sadrzaja dva elementa */ 
void swap(void *v[], int i, int j) ; 
/*poredi niske numericki prema vrednosti brojeva koje predstavljaju */ 
int ncmp(const void *p1, const void *p2);
/*poredi niske leksikografski */ 
int scmp(const void *p1, const void *p2);
 /* ucitavanje ulaznih reda */ 
int readlines( char *lineptr[], int maxlines);    
/* unos linije i odredjivanje duzine */ 
int getline( char s[], int lim ) ; 
/* ispis linija teksta */ 
void writelines(char *lineptr[], int nlines ); 
/* ispis izlaznog reda */ 
void ispis( char *lineptr[], int i); 
  
main(int argc, char *argv[]) 
 { 
  int nlines;         /* broj procitanih ulaznih redova */ 
 int vrsta = 0;   /* vrsta poredjenja:1 ako je numericko*/ 
 // obrada komandne linije 
 if( argc > 1 && strcmp(argv[1],"-n") == 0 ) vrsta=1;       //  argv[1] je pokazivac na nisku - mora strcmp 
 if( argc > 2 ) puts("\n\nvisak parametara - ignorisu se!"); 
 /*obrada linija sa ulaza */ 
   if( (nlines = readlines(lineptr, MAXLINES)) >= 0 ) 
      { 
   /*uporediti sa qqsort-om iz 85. */ 
      qsort( lineptr, nlines, sizeof(lineptr[0]), (vrsta? &ncmp: &scmp)); 
      writelines(lineptr, nlines); 
      return 0; 
  } 
    else 
    { 
     printf("Greska: ulaz predugacak za sortiranje\n"); 
     return 1; 
 } 
} 
void swap(void *v[], int i, int j) 
{  void *temp; 
   temp = v[i];    v[i] = v[j];    v[j] = temp; 
} 
  int readlines( char *lineptr[], int maxlines)     /* ucitavanje ulaznog reda */ 
{ 
int len ;    /*duzina ucitane linije */ 
int nlines ; /*broj ucitanih linija */ 
char *p;     /*tekuca linija */ 
char line[MAXLEN]; // line je pomocni bafer 
nlines = 0; 
/*ucitavanje linija do markera kraja ili do limita */ 
while((len = getline(line, MAXLEN)) > 0 ) 
   if( nlines >= maxlines || (p = (char *) malloc(len)) == NULL) 
    return -1; 
    else 
 { 
  line[len - 1] = '\0';      /* izbaci novi red */ 
  strcpy(p, line); 
  lineptr[nlines++] = p; 
 } 
 return nlines; 
} 
/* unos linije i odredjivanje duzine  (sa '\0') */ 
int getline( char s[], int lim ) 
{ int c, i; 
  i = 0; 
  while( --lim > 0 && (c = getchar()) != EOF && ( c != '\n' ) ) 
        s[i++] = c; 
  if( c == '\n' )s[i++] = c; 
  s[i] = '\0'; 
  return i; 
} 
/* ispis linija teksta */ 
void writelines(char *lineptr[], int nlines ) 
{ 
   int i=0; 
   if (nlines) puts("sortirane linije\n"); 
   else puts("nije bilo linija na ulazu!"); 
   for(; i < nlines; i++) ispis(lineptr,i); 
} 
/* ispis izlaznog reda */ 
void ispis( char *lineptr[], int i) 
{ 
 /* simulacija printf("%s\n", lineptr[i]);  */ 
   int k; 
     for( k = 0; k < strlen(lineptr[i]); k++) 
  putchar( lineptr[i][k] );   // ispis znak po znak !!! 
    printf("\n"); 
} 
int scmp(const void *p1, const void *p2)
{  char *s1= *(char **)p1;  /* p1 je pokazivac na element niza stringova, tj. tipa char **, 
a f-ja cmp  mora da radi sa podatkom tipa char * tj. f-ja strcmp */
   char *s2= *(char **)p2;
      return ( strcmp (s1,s2) );
}
int ncmp(const void *p1, const void *p2)
{ 
  double v1,v2; 
 char *s1= *(char **)p1;  /* p1 je pokazivac na element niza stringova, tj. tipa char **, 
a f-ja cmp  mora da radi sa podatkom tipa char * tj. f-ja strcmp */
   char *s2= *(char **)p2;
  v1=atof(s1); 
  v2=atof(s2); 
  if (v1 < v2)  return -1; 
  else if (v1 > v2) return 1; 
      else return 0; 
}

Jelena Grmuša Osnovi programiranja

e-mail: Jelena Grmuša


Copyright © 2002, Jelena Grmusa
Poslednja izmena: februar 2004.
URL: http://www.matf.bg.ac.yu/~jelenagr/op/