Vežbe iz Osnova programiranja IV - nizovi kao parametri fukcije, nizovi karakera, niska ili string



Prenos niza u f-ju

79. Demonstrira prenos nizova u funkciju - preneti niz se moze MENJATI!!!. NCP koji ucitava rec sa standdardnog ulaza koja ima ne vise od 100 karaktera i ispisuje je na standardni izlaz. Rec je ma koja niska karaktera koja ne sadrzi beline (blanko, tab, prelaz u novi red,...). Ucitanu rec cuvati u stringu (nisci).

U programskom jeziku C string(niska) je niz karaktera koji se zavrsava specijalnom zankom '\0'.
Primer: niska "x" je niz sa dva elementa koji se moze deklarisati i kao
char niska[]={'x', '\0'}

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

/* Funkcija ucitava rec sa standardnog ulaza i smesta je u niz karaktera s.
Ovo uspeva zbog toga sto se po vrednosti prenosi adresa pocetka niza,
a ne ceo niz */
void get_word(char s[])
{
   int c, i = 0;  /*znak sa ulaza, brojac u ciklusu */

   while (!isspace(c=getchar())) s[i++] = c;

   s[i] = '\0';  /*OBAVEZAN kraj stringa u C-u */
}

main()
{
   /* Obavezno je alocirati memoriju za niz karaktera */
   char s[100];

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

80. Funkcija za ispis niza brojeva - demonstrira prenos nizova brojeva u funkciju.

#include <stdio.h>

/* Nizovi se prenose tako sto se prenese adresa njihovog pocetka.
    Uglaste zagrade mogu da ostanu prazne!  Zasto?
    Nizove je najcesce potrebno prenositi zajedno sa dimenzijom niza (osim niski karaktera) */
void print_array(int a[], int n)
{
     int i; /*brojac u ciklusu */

     for (i = 0; i < n; i++) printf("%d ",a[i]);

     putchar('\n');

     /* Obratite paznju na ovaj sadrzaj koji se stampa!!! */
       printf("sizeof(a) - u okviru fje : %d\n", sizeof(a));
}

main()
{
    int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};  /*deklaracija niza sa inicijalizacijom clanova. Koliko je a[1]? */

    printf("sizeof(a) - u okviru main : %d\n", sizeof(a));

    print_array(a, sizeof(a)/sizeof(int));
}

Izlaz:
sizeof(a) - u okviru main : 36
1 2 3 4 5 6 7 8 9
sizeof(a) - u okviru fje : 4


81.  Funkcije za rad sa stringovima: 
Funkcija za ispis niske karaktera - demonstrira prenos niske karaktera u funkciju

#include <stdio.h>

/* Uz nisku karaktera nije potrebno prenositi dimenziju ukoliko se postuje dogovor
    da se svaka niska zavrsava karakterom '\0'.*/
void print_string(char s[])
{
   int i; /* brojac u ciklusu */
 
  for (i = 0; s[i]; i++) putchar(s[i]);
}
main()
{
print_string("Zdravo\n");
}

Izlaz:
Zdravo



82. Skalarni proizvod dva niza brojeva - prenos dva niza kao parametr afunkcije

#include <stdio.h>
long mnozi(int x[],int y[],int n);

main()
{
   int a[]={1,2,3,4,5,6}, b[]={8,7,6,5,4,3};
   printf("Skalarno a*b= %ld\n",mnozi(a,b,6));
}

long mnozi(int x[ ],int y[ ],int n) { 
  int br;   /* brojac u ciklusu */
  long suma=0; /* vrednost skalarnog proizvoda */

  for(br=0;br<n;br++) suma=suma+x[br]*y[br];

  return suma;
}

Izlaz:
Skalarno a*b= 98



83. NCP koji vrsi linearnu pretragu niza.

#include <stdio.h>

/* Funkcija proverava da li se dati element x nalazi
u datom nizu celih brojeva.
Funkcija vraca poziciju u nizu na kojoj je x pronadjen
odnosno -1 ukoliko elementa nema.
*/
int linearna_pretraga(int niz[], int br_elem, int x)
{
    int i; /*brojac u ciklusu */

  /* testira se svaki clan niza a[i] na jednakost sa vrednosti promenljive x */
   for (i = 0; i<br_elem; i++)
       if (niz[i] == x) return i;

return -1;
}

main()
{
    int a[] = {4, 3, 2, 6, 7, 9, 11};
    int x;
    int i;
    int br_elem = sizeof(a)/sizeof(int);

printf("Unesi broj koji trazimo : ");
scanf("%d",&x);
i = linearna_pretraga(a, br_elem, x);

if (i == -1) printf("Element %d nije nadjen\n",x);
else printf("Element %d je nadjen na poziciji %d\n",x, i);
}


Studentima se preporučuje da samostalno urade i testiraju rešenja II i III grupe zadataka koji se mogu pogledati na stranici vezba.html

NISKE (stringovi) u C-u: podsećanje

/* Primer programa koji  uvodi niske karaktera terminisane nulom */
#include <stdio.h>
main()
{
    /* Poslednji bajt niske karaktera s se postavlja na '\0' tj. 0 */
     char s[] = {'a', 'b', 'c', '\0' };

/* Kraci nacin da se postigne prethodno */
     char t[] = "abc";


    /* Ispis niske s karakter po karakter - I nacin*/
     int i;
      for (i = 0; s[i] != '\0'; i++)  putchar(s[i]);
      putchar('\n');


     /* Ispis niske s koristeci funkciju printf  - II nacin*/
         printf("%s\n", s);

     /* Ispis niske t karakter po karakter-I nacin*/
     for (i = 0; t[i] != '\0'; i++) putchar(t[i]);
      putchar('\n');

    /* Ispis niske t koristeci funkciju printf - II nacin*/
      printf("%s\n", t);
}


84. NCP koji čita sa standardnog ulaza liniju teksta ograničene dužine (ograničenje broja karaktera se zadaje u programu, MAXLINE), upisuje je u string i ispisuje na standardni izlaz.


Ovog puta sadrzaj linije necemo koristi upotrebom fukcije scanf, jer ona cita zapravo reci, a jedna linija moze imati vise reci. sami cemo napisati korisnicku funkciju getline.
Primer linije:
Moj omiljeni predmet je Programiranje 1.


#include <stdio.h>


#define MAXLINE 1000  /*limit duzine linije */
#define USPEH 0


int getline( char Line[], int Limit);
/* ucitava sa ulaza liniju limitirane duzine u nisku Line i vraca njenu duzinu */
 

/* glavni program */
main()
{
int duz;  /*broj ucitanih  znakova*/
char linija[MAXLINE];     /*sadrzaj linije */
printf("Unesite red  teksta \n");
duz=getline(linija,MAXLINE);


printf("Uneseno je \n"); printf("%s", linija);
return USPEH;


}


/* getline: ucitava liniju i vraca njenu duzinu */
int getline( char Line[], int Limit)
{
 int znak, indeks;
 for( indeks=0; indeks<Limit-1 && (znak=getchar())!=EOF && znak!='\n'; ++indeks)
  Line[indeks]=znak;
 

if( znak=='\n' )
 {
  Line[indeks++]=znak;
  //Line[indeks]=znak;
  //++indeks;
 }


 Line[indeks]='\0';
 return indeks;
}

85. NCP koji će sve linije teksta sa standardnog ulaza ispisati s obrnutim sadržajem na standardni izlaz. Broj linija NIJE unapred ograničen, ali je svaka linija sa ulaza ograničene dužine.


#include <stdio.h>
#define MAXLINE 1000


/* deklaracija funkcija */
int getline( char s[], int Max); /* ucitava liniju i vraca njenu duzinu */
void reverse( char s[] );/* obrce string s */


/* glavni program */
main()
{
int Len; /*duzina ucitane linije */
char Line[MAXLINE];/* sadrzaj ucitane linije */


/* ucitavanje linija sa ulaza limitirane duzine do markera kraja fajla */
while ( (Len=getline(Line,MAXLINE)) > 0 )
{ reverse( Line );

/* na izlaz se salje linija okrenuta naopacke */
printf( "%s\n", Line );
}
return 0;
}
/* reverse: obrce string */
void reverse( char s[] )
{
  int indeks, br; /* brojacke promenljive */
  char  Temp;/* posrednik u razmeni dva karaktera sa iz leve i desne polovine stringa */

  for(indeks=0; s[indeks]!='\0'; ++indeks )   ;

  br=indeks-1; /* br cuva broj karaktera niske s */
/* string s ima br karaktera ne racunajuci \0 i poslednji karakter razlicit od \0 je s[br] */
 

   for( indeks=0; indeks<br; indeks++, br-- )
 {
/* izmena sadrzaja dva karktera: karaktera na i-toj poziciji udesno od pocetka stringa i i-toj poziciji ulevo od kraja stringa */
  Temp=s[indeks];
  s[indeks]=s[br];
  s[br]=Temp;
 }
 return;
}


/* getline: ucitava liniju i vraca njenu duzinu */
int getline( char s[], int Limit)
{
int znak, indeks;
for( indeks=0; indeks<Limit-1 && (znak=getchar())!=EOF && znak!='\n'; ++indeks)     s[indeks]=znak;


if( znak=='\n' )
{s[indeks]=znak;   ++indeks;
}


s[indeks]='\0';
return indeks;
}

86. NCP koji će učitati liniju limitirane duzine sa standardnog ulaza i ispisati na standardni izlaz bez
a) malog slova 'x'  b) bez malih slova 'x', 'y' c) bez malog slova 'x' i slova y (bilo malo ili veliko)

PRIMER

ULAZ

IZLAZ a)

IZLAZ b)

IZLAZ c)

MAX xyzYYYZ

MAX yzYYYZ

MAX zYYYZ

MAX zZ



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

#define MAXLINE 1000
int getline( char line[], int limit);
/* ucitava liniju sa ulaza limitirane duzine u string line i vraca njenu duzinu */

void squeeze( char s[], int ch); /* uklanja karakter ch iz stringa s */

main()
{  int duz; /* duzina ucitane linije */
  char linija[MAXLINE]; /* sadrzaj linije sa ulaza */

   printf("Unesite red teksta \n");
   duz=getline(linija,MAXLINE);
   squeeze(linija,'x');
    printf("Uneseni tekst bez slova x \n");
   printf("%s", linija);

/* drugi po redu poziv f-je squeeze radi sa linijom iz koje je prethodno izbaceno malo slovo 'x' */
   squeeze(linija,'y');
    printf("Uneseni tekst bez slova x, y \n");
   printf("%s", linija);

    squeeze(linija,'Y');
    printf("Uneseni tekst bez slova x, y, Y \n");
  printf("%s", linija);
  return 0;
}




/* squeeze: uklanja znakove iz stringa */
void squeeze( char niska[], int ch)
{int indeks, tekuci; /*brojacke promenljive */


for( indeks=tekuci=0; niska[indeks]!='\0'; indeks++)

if(niska[indeks] != ch)    niska[tekuci++]=niska[indeks];

/* ako je znak niske na poziciji indeks razlicit od znaka ch, onda je taj znak "zasluzio" da ostane u nisci i zadrzavamo ga na poziciji tekuci, a nakon naredbe dodele uveca se tekuci za 1, tj. vrsi se priprema za sledeci znak niske koji je zasluzio" da ostane u nisci */
 

/*obavezno je zavrsiti nisku na poziciji tekuci*/
niska[tekuci]='\0';
}




/* getline: ucitava liniju i vraca njenu duzinu */
int getline( char lin[], int lim)
{int  ch, indeks;
for( indeks=0; indeks<lim-1 && (ch =getchar())!=EOF &&  ch!='\n'; ++indeks) lin[indeks]=ch;
if( ch=='\n' )      lin[indeks++]=ch;
lin[indeks]='\0';
return indeks;
}

 

87.

/* strlen, strcpy, strcat, strcmp, strchr, strstr -manipulacija niskama karaktera */
Napisati C funkcije koje implementiraju funkcije iz biblioteke string.h i to:
1. funkciju string_length koja implementira funkciju strlen iz zaglavlja string.h 
2. funkciju string_copy koja impementira funkciju strcpy iz string.h
3. funkciju string_concatenate koja implementira funkciju strcat iz string.h
4. funkciju string_char koja implementira funkciju strchr iz string.h
5. funkciju string_last_char koja pronalazi poslednju pojavu karaktera u nisci
6. funkciju string_string koja slicno funkciji strstr iz string.h proverava da li je neka niska podniska druge
NCP koji ilustruje pozive ovih funkcija.

#include <stdio.h>

/* Izracunava duzinu stringa */
int string_length(char s[])
{
   int i;
   for (i = 0; s[i]; i++) ;
   return i;
}



/* Kopira string src u string dest. Pretpostavlja da u dest ima dovoljno prostora. */
void string_copy(char dest[], char src[])
{
   /*Kopira karakter po karakter,sve dok nije iskopiran karakter '\0' */
    int i;
      for (i = 0; (dest[i]=src[i]) != '\0'; i++) ;

                 /* Uslov != '\0' se, naravno, moze izostaviti : for (i = 0; dest[i]=src[i]; i++);   */
}


/* Nadovezuje string t na kraj stringa s. Pretpostavlja da u s ima dovoljno prostora. */
void string_concatenate(char s[], char t[])
{
    int i, j;

     /* Pronalazimo kraj stringa s */
      for (i = 0; s[i]; i++);

      /* Vrsi se kopiranje, slicno funkciji string_copy, ali ne od pocetka niske s, vec od kraja niske s */
      for (j = 0; s[i] = t[j]; j++, i++) ;

}


/* Vrsi leksikografsko poredjenje dva stringa.
Vraca :
0 - ukoliko su stringovi jednaki
<0 - ukoliko je s leksikografski ispred t
>0 - ukoliko je s leksikografski iza t
*/
int string_compare(char s[], char t[])
{
    int i;

   /* Petlja tece sve dok ne naidjemo na prvi razliciti karakter */
   for (i = 0; s[i]==t[i]; i++)
           if (s[i] == '\0')  return 0; /* Naisli smo na kraj oba stringa, a nismo nasli razliku */
                

    /* s[i] i t[i] su prvi karakteri u kojima se niske razlikuju.
     Na osnovu njihovog odnosa (razlike ASCII vrednosti), odredjuje se odnos stringova < ili > ili ==*/
        return s[i] - t[i];
}



/* Pronalazi prvu poziciju karaktera c u stringu s, odnosno -1 ukoliko s ne sadrzi c */
int string_char(char s[], char c)
{
   int i;

    for (i = 0; s[i]; i++)
         if (s[i] == c)  return i;

/* NIKAKO
   else  return -1;
*/

/* Nije nadjeno */
   return -1;
}


/* Pronalazi poslednju poziciju karaktera c u stringu s, odnosno -1 ukoliko s ne sadrzi c */
int string_last_char(char s[], char c)
{
   int i;

  /* Najpre pronalazimo kraj stringa s */
   for (i = 0; s[i]; i++) ;

    /* Krecemo od kraja i trazimo c unazad */
       for (i--; i>=0; i--)
           if (s[i] == c)  return i;

    /* Nije nadjeno */
      return -1;


    /* ILI drugi nacin bi bio koristeci string_length :
                 for (i = string_length(s) - 1; i>0; i--)
                      if (s[i] == c)  return i;
               return -1;
     */

}


/* Proverava da li string str sadrzi string sub.
Vraca poziciju na kojoj sub pocinje, odnosno -1 ukoliko ga nema
*/
int string_string(char str[], char sub[])
{
    int i, j;
  
/* Proveravamo da li sub pocinje na svakoj poziciji i */
  for (i = 0; str[i]; i++)
         /* Poredimo sub sa str pocevsi od poziciji i sve dok ne naidjemo na razliku */
      for (j = 0; str[i+j] == sub[j]; j++)
        /* Nismo naisli na razliku a ispitali smo sve karaktere niske sub */
          if (sub[j+1]=='\0') return i;

/* Nije nadjeno */
return -1;

}

main()
{
char s[100];
char t[] = "Zdravo";
char u[] = " svima";

string_copy(s, t);
printf("%s\n", s);

string_concatenate(s, u);
printf("%s\n", s);

printf("%d\n",string_char("racunari", 'n'));

printf("%d\n",string_last_char("racunari", 'a'));

printf("%d\n",string_string("racunari", "rac"));

printf("%d\n",string_string("racunari", "ari"));

printf("%d\n",string_string("racunari", "cun"));

printf("%d\n",string_string("racunari", "cna"));

}



Izlaz:
Zdravo
Zdravo svima
4
5
0
5
2
-1

Zadaci za vežbu (praktikum) - niske i pretraga niski:

/* Linearna pretraga u niza karaktera
NCP koji sa standardnog ulaza unosi pomocu funkcije scanf nisku sa ne vise od 20 karaktera i proverava da li niska sadrzi znak @ */

Postupak linearnog pretraživanja

Traženi element x se može naći lineranim (sekvencijalnim) pretraživanjem.
Redom se porede elementi ulaznog niza v sa vrednošću od x, sve do prvog elementa v[i] za koji važli v[i] >=x.
Tada, ako je:

Ako je svaki element niza v manji od vrednosti od x, onda se x ne nalazi u nizu v (izvrsi se n poredjenja).

#include <stdio.h>
#include <string.h>
/* Funkcija proverava da li se dati element x nalazi 
   u datom nizu a. 
   Funkcija vraca poziciju u nizu na kojoj je x pronadjen
   odnosno -1 ukoliko elementa nema.
*/
int linear_search(char a[], int n, int x) 
{
        int i;
        for (i = 0; i<n; i++)
                if (a[i] == x)
                        return i;
                /* nema potrebe za  else!!! */
        return -1;      
}

main()
{
        char a[21] ; /*niska sa stdin */
                  int n; /*broj unetih karaktera niske a*/
        int i; /*brojacka promenljiva*/
        printf("Unesite nisku : ");
         scanf("%s",a);
        n = strlen(a);
        i = linear_search(a, n, '@');
        if (i == -1)
                printf("Karakter @ nije nadjen\n");
        else    
                printf("Karakter @  je na poziciji %d\n", i);
}


/* Binarna pretraga u niza karaktera
NCP koji sa standardnog ulaza unosi pomocu funkcije scanf leksikografski uredjenu nisku sa ne vise od 20 karaktera i proverava da li niska sadrzi znak @. ASCII(@) = 64 */

/*-----------------------Binarna pretraga niza celih brojeva - iterativna verzija-------------------------------*/

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

/* Funkcija proverava da li se element x javlja unutar niske a.
   Funkcija vraca poziciju na kojoj je element nadjen odnosno
   -1 ako ga nema.
 
   !!!!! VAZNO !!!!!
   Pretpostavka je da je niska a sortirana
*/

int binary_search(char a[], int n, int x)
{
        /* Pretrazujemo interval [l, d] */
        int l = 0;
        int d = n-1;
        
        /* Sve dok interval [l, d] nije prazan */
        while (l <= d)
        {
                /* Srednja pozicija intervala [l, d] */
                int s = (l+d)/2;
                
                /* Ispitujemo odnos x i srednjeg elementa a[s]*/
                if (x == a[s])
                        /* Element je pronadjen */
                        return s;
                else if (x < a[s])
                {
                        /* Pretrazujemo interval [l, s-1] */    
                        d = s-1;
                }
                else
                {
                        /* Pretrazujemo interval [s+1, d] */
                        l = s+1;
                }
        }

        /* Element je nadjen */
        return -1;      
}

main()
{
        char a[21] ; /*niska sa stdin */
                  int n; /*broj unetih karaktera niske a*/
        int i; /*brojacka promenljiva*/
        printf("Unesite nisku : ");
        scanf("%s",a);

        i = binary_search(a, strlen(a), '@');
        
        if (i==-1)
                printf("Nema karaktera @\n");
        else
                printf("Pronadjen @ na poziciji %d\n", i);
}



Odnos broja poredjenja kod linearne i binarne pretrage


Zadatak 1. NCP koji sa standardnog ulaza unosi nisku sa ne vise od 20 karaktera i pronalazi poziciju poslednje pojave karaktera @.

NAPOMENA: obrnut nisku, naci poziciju 1. pojave linearnom pretragom i tu poziciju oduzeti od strlen(niska)


Zadatak 2. NCP koji sa standardnog ulaza unosi nisku sa ne vise od 20 karaktera koja sadrzi e-mail adresu i ispisuje na standardni izlaz user name. Pretpostaviti da email adresa se zadaje u formi username@host.domen. Npr. mr05007@yubc.net, mr05007@alas.matf.bg.ac.yu

NAPOMENA: kao u funkciji linearne pretrage naci poziciju prve pojave karaktera @ i ispis vrsiti od 0-te do te pozicije.


Zadatak 3. NCP koji sa standardnog ulaza unosi nisku sa ne vise od 20 karaktera koja sadrzi e-mail adresu i ispisuje na standardni izlaz naziv drzave domena. Pretpostaviti da email adresa se zadaje u formi username@host.domen i da domen obavezno sadrzi naziv drzave Npr. mr05007@gauss.matf.br.ac.de, mr05007@alas.matf.bg.ac.yu

NAPOMENA: naci poziciju poslednje pojave . u nisci i ispis vrsiti od te pozicije do kraja niske


Zadatak 4. NCP koji sa standardnog ulaza unosi nisku sa ne vise od 20 karaktera koja sadrze e-mail studenta Matematickog fakulteta, a na standardni izlaz ispisuje izmenjenu nisku tako da naziva servera alas iza znaka @ bude zamenjen nazivom arhimed (primer: niska="mr05007@alas.matf.bg.ac.yu" se transformise u niska="mr05007@arhimed.matf.bg.ac.yu")

NAPOMENA: moze se vrsiti ispis do prve pojave @, te ispisati arhimed. te vrsiti ispis od prve pozicije tacke (iza @) do kraja niske
Moze se izvrsiti i pronalazenje prve pozicije NISKE alas i od te pozicije izvrsiti prepisivanje niske "arhimed"


Zadatak 5. NCP koji sa standardnog ulaza unosi dve niske sa ne vise od 20 karaktera koje sadrze e-mail adrese, a na standardni izlaz ispisuje da li su im jednaka korisnicka imena. Na primer, niska1="mr05007@alas.matf.bg.ac.yu" , niska2="mr05007@EUnet.yu" sadrze isto korisnicko ime mr05007

NAPOMENA: nalazi prve pozicije @ u obe niske i poredi podniske do te pozicije


Zadatak 6. NCP koji sa standardnog ulaza unosi niz linija sa ne vise od 80 karaktera, pronalazi najduzu liniju i ispisuje na standardni izlaz broj pojava svake dekadne cifre. Izvestaj treba urediti u nerastucem poretku broja pojava cifara, tj. najpre se ispisuje broj pojava za najfrekventnije cifre.
PRIMER: Neka najduza linija je: 222 + 35 je 257 gledano u sistemu sa osnovom 10.
Izvestaj: Cifra 2 se pojavljuje 4 puta, cifra 5 se pojavljuje 2 puta, cifra 0 se pojavljuje 1 put, cifra 1 se pojavljuje 1 put...

NAPOMENA: broj pojava cifri se moze cuvati u nizu, ali se niz mora sortirati, pazecu pri tom da i kad se sortira cifra[i] mora biti broj pojave cifre i sto nece vaziti nakon sortiranja. Zato treba porazmisliti o memorisanju za koju cifru j=0..9 clan cifra[i] je broj pojave cifre j. Ili uz malu pomoc algebre, uociti da broj pojave svake cifre je <=80, te formirati niz brojeva oblika broj=80*i*10+cifra[i], gde broj%800 je cifra[i], broj/800 je cifra i



88. NCP koji prihvata sa standardnog ulaza liniju limitirane dužine i ispisuje je na standardni izlaz sa uklonjem belinama zdesna.


#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define MAXLINE 1000
/*getline: ucitava sa ulaza liniju limitirane duzine u line i vraca njenu duzinu */
int getline( char line[], int lim);

/*iseca beline sdesna iz niske i vraca duzinu isecene niske */
int rtrim( char niska[] );

main()
{int duz; /* duzina ucitane linije */
char line[MAXLINE];/* sadrzaj linije sa ulaza */

printf("Unesite string \n");
duz=getline(line,MAXLINE);
printf("Broj znakova u stringu je %d\n", strlen(line));

/*isecanje belina sa kraja stringa*/
duz=rtrim(line);
printf( "Sdesna iseceni string\n%s\nsadrzi %d znakova\n", line, duz );
return 0;
}

 

/* rtrim: iseca beline sa desne strane */
int rtrim( char niska[] )
{int desnapoz; /* brojacka promenljiva */

/*pocev od kraja niska prelazi se preko belina (ako postoje) i ... */
for( desnapoz=strlen(niska)-1; desnapoz>0; desnapoz-- )

/* ... cim se naidje na znak u nisci razlicit od: blanko, tabulatora i znaka prelaska u novi red ... */
if( niska[desnapoz]!=' ' && niska[desnapoz]!='\t' && niska[desnapoz]!='\n'
/*!isspace(niska[desnapoz])*/ )
/* zaustavimo se kod tog znaka i izadjimo iz ciklusa */
   break;
 

/* kako niska[desnapoz] je prvi karakter "otpozadi" koji nije blanko, tab, new line, onda moramo iseceni string zavrsiti na poziciji desnapoz+1 */
niska[desnapoz+1]='\0';
return desnapoz+1; /* vraca se duzina isecenog stringa */
}


/* getline: ucitava liniju i vraca njenu duzinu */
int getline( char line[], int lim)
{int znak, indeks;
for( indeks=0; indeks<lim-1 && (znak=getchar())!=EOF && znak!='\n'; ++indeks)
line[indeks]=znak;


if( znak=='\n' ) line[indeks++]=znak;
line[indeks]='\0';
return indeks;

}

89. NCP koji čita tekst sa standardnog ulaza i svaku linju teksta ispisuje na standardni izlaz šifrirane po shemi koja utiče samo na slova.

SHEMA

A

B

...

Y

Z

a

b

...

y

z

c

d

...

a

b

D

E

...

B

C


Broj linija teksta nije unapred poznat, linije su limitirane dužine. Može se pretpostaviti da mašinski set znakova odgovara ASCII kôdu.

PRIMER

ULAZ

IZLAZ

1. Baba 23/05

1. dDED 23/05

32. Zaza 34/04

32. bDCD 34/04




#include <stdio.h>
#define MAXLINE 1000    /*maksimalna duzina linije */
/* deklaracija funkcija */
int getline( char s[], int MaxLine);
void Cezar( char s[],int pom );
/* glavni program */
main()
{ int duz;        /*duzina tekuce linije */
   char s[MAXLINE];        /*tekuca linija */
  while( (duz=getline(s,MAXLINE)) > 0 )
   {
         Cezar( s,3 );       /*obrada linije po zadatoj shemi */
       printf( "%s\n", s );
   }
  return 0;
}
/* Cezar: sifrira string Cezarovom sifrom, ASCII  */
void Cezar( char s[] ,int pomeraj)
{
  int i;
  for(i=0; s[i]!='\0'; ++i )
  { if  ( s[i]>='A' && s[i]<='Z') s[i]='a' +(pomeraj-1   +     s[i]-'A')%26;
     else  if  ( s[i]>='a' && s[i]<='z') s[i]='A'+   ( pomeraj +    s[i]-'a') %26;
  }
return;
}
/* getline: ucitava liniju i vraca njenu duzinu */
int getline( char Line[], int Limit)
{ int znak, indeks;
   for( indeks=0; indeks<Limit-1 && (znak=getchar())!=EOF && znak!='\n'; ++indeks)  Line[indeks]=znak;
   if( znak=='\n' )
     {  Line[indeks]=znak;
         ++indeks;
      }
   Line[indeks]='\0';
   return indeks;
}


ZADACI ZA VEZBU

1. NCP koji ce ucitati sa standardnog ulaza dve reci, uporediti ih leksikografski i manju od njih ispisati malim slovima, vecu od njih velikim slovima. Ukoliko su niske jednake, ispisati poruku da su jednake. Pretpostaviti da svaka rec ima ne vise od 40 karaktera.

ULAZ 123abcDef abc..de IZLAZ 123abcdef ABC..DE

2. NCP koji ce ucitavati sa standardnog ulaza reci limitirane duzine (sa ne vise od 40 karaktera) do markera kraja datoteke i ispisati na standardni izlaz najvecu od njih (leksikografski gledano). Ako postoji vise pojava najvece reci, ispisati je tacno jednom.

ULAZ: Programiranje1 je moj omiljeni predmet, jer programiranje volim i time nameravam da se bavim. ^D

IZLAZ volim




Dva zadatka u kojima se celi brojevi reprezentuju kao niske svojih cifara

90. NCP koji će učitati sa standardnog ulaza u jednoj liniji nisku cifara koja reprezentuje pozitivan ceo broj strogo manji od maksimalne vrednosti za tip int, kovertovati ga u numerički ekvivalent (funkcija atoi, str. 41 K&R) i ispisati broj za 1 veći.

NISKA "000723" predstavlja broj 723 čija vrednost se formira (po Hornerovoj shemi???) u formi ('7'-'0')*100 + ('2'-'0')*10 + ('3'-'0') = 7*100 + 2*10 + 3*100 = 10 * ( 10 * (7) + 2) + 3


#include <stdio.h>
#define MAXLINE 1000
int getline( char s[], int Limit);
int atoi( char s[] );
/* glavni program */
main()
{
  int duzina,Number; /*broj unetih cifara broja, numericka vrednost broja */
char s[MAXLINE]; /*niska cifara unetog broja */
printf("Unesite pozitivan ceo broj strogo manji od maximalnog int \n");
duzina=getline(s,MAXLINE);
Number=atoi(s);
printf( "Uvecanjem za jedan se dobija:\n%d\n", ++Number );
return 0;
}
/* atoi: ascii to integer */
int atoi( char s[] )
{   int i, Num=0; /*brojacka promenljiva, numericki ekvivalent niske s*/

/* formiranje vrednosti broja od dekadnih cifara s[i] niske s*/
    for( i=0; s[i]>='0' && s[i]<='9'; ++i) Num=10*Num+(s[i]-'0');
 
 return Num;
}
/* getline: ucitava liniju i vraca njenu duzinu */
int getline( char Line[], int Lim)
{
 int znak, indeks;
 for( indeks=0; indeks<Lim-1 && (znak=getchar())!=EOF && znak!='\n'; ++indeks)
  Line[indeks]=znak;
 if( znak=='\n' )
 {  Line[indeks]=znak;
     ++indeks;
 }
 Line[indeks]='\0';
 return indeks;
}

91. NCP koji učitava nisku koja predstavlja ili heksadekadnu konstantu (npr. 0x1a ili 0XFF, pocinje sa 0x ili 0X) ili heksadekadni broj koji je strogo manji od maksimalne vrednosti INT_MAX. Potom konvertuje nisku u numerički dekadni ekvivalent i ispisuje broj za 1 veći.

PRIMER

ULAZ

DEKADNI EKVIVALENT

++IZLAZ

0XA

10

11

0x7ffe

32766

32767




#include <stdio.h>
#include <ctype.h>
#define MAXLINE 1000
int getline( char s[], int Limit);
unsigned htoi( char s[] );
int hexvalue( int znak );

main()
{
int duz; /* duzina ucitane linije */
unsigned Number; /* numericki ekvivalent niske kojom je predstavljena heksadekadna vrednost sa ulaza */
  char linija[MAXLINE]; /* linija sa ulaza */

  printf("Unesite broj \n");
   duz=getline(linija,MAXLINE);
    Number=htoi(linija);
  printf( "Inkrementirani broj je:\n%u\n", ++Number );
return 0;
}

/* hvalue: vrednost hexadecimalne cifre  */
int hexvalue( int znak )
{
  if(isdigit(znak))   return(znak-'0');
   if    (znak>='A' && znak<='F')      return(znak-'A'+10);
   if     (znak>='a' && znak<='f')       return(znak-'a'+10);
return 0;
}
/* htoi: hexadecimal ascii -> integer */
unsigned htoi( char s[] )
{
   int Pos;
 unsigned  Num;
   if((s[0]=='0' && s[1]=='x')     || (s[0]=='0' && s[1]=='X') )        Pos=2;
  else   Pos=0;
for(Num=0; isdigit(s[Pos])
    || (s[Pos]>='A' && s[Pos]<='F')
   || (s[Pos]>='a' && s[Pos]<='f'); ++Pos)
  Num=16*Num+hexvalue(s[Pos]);
return Num;
}
/* getline: ucitava liniju i vraca njenu duzinu */
int getline( char Linija[], int Limit)
{
 int  znak, indeks;
 for( indeks=0; indeks<Limit -1&& (znak=getchar())!=EOF && znak!='\n'; ++indeks)
  Linija[indeks]=znak;
 if( znak=='\n' )
 {Linija[indeks]=znak;
                 ++indeks;
 }
 Linija[indeks]='\0';
 return indeks;
}


Jelena

Programiranje 1


e-mail: Jelena Grmuša