Ponavljanje : Formatirani izlaz i ulaz

Slanje podataka od strane korisnika (čoveka) ka računaru nazivamo ulaz (input). Tok podataka u suprotnom smeru, tj. od računara ka korisniku nazivamo izlaz (output).

Izlaz

Funkcija koju smo prvu koristili je puts - ona može da ispiše niz slova (string) direktno na ekran i to je jedino što se može raditi sa tom funkcijom. Pomoću nje se ne može prikazati vrednost neke celobrojne promenljive.

Zašto?

Zato što je puts tako napravljena da joj se u zagradama može staviti samo string koji će da se ispiše. Nikakvi drugačiji parametri neće biti prihvaćeni, i ako pokušate, doći će do greške prilikom kompajliranja.

Da bismo u programskom jeziku "C" prikazali vrednost neke promenljive tipa int, float ili char koristimo funkciju printf (print formatted).

Pomoću ove funkcije može da se prikaže više različitih vrednosti različitih tipova i da se sve to pomeša sa tekstom. Za početak neće biti prikazane sve opcije već samo neke koje ćemo koristiti.

Funkcija printf ima više osobina: ne kaže se koliko argumenata mora da se postavi u zagradama; jedino što se zahteva je da mora da postoji bar jedan argument; i da prvi argument u zagradi mora da bude string (rečenica napisana između navodnika ".... "); a svi sledeći argumenti mogu da budu bilo kojeg tipa. To nije nešto preterano komplikovano.

Prvi argument koji mora da se nalazi u zagradama se naziva format. To možete shvatiti kao recept ili kao specifikaciju na osnovu koje će printf funkcija da prikaže i sve dodatne argumente.

Funkcija printf će da pažljivo pročita instrukciju i da iz nje nauči koje podatke treba da prikaže na ekranu na koji način će da ih prikaže. U nastavku je dato nekoliko primera pomoću kojih je to malo jasnije objašnjeno. Prvi primer je jednostavan - treba da se pomoću printf prikaže neki tekst. To radimo na sledeći način:

 

printf("Ovo je samo tekst");

U sledećem primeru ćemo da prikažemo i vrednost jedne celobrojne promenljive:

printf("Do sada izbrojano %d ovaca",BrojOvaca);

 

Kao što može da se vidi, printf sada ima dva argumenta. Prvi je format. Drugi je promenljiva tipa int. Ako pogledate u format, primetit ćete čudan znak: %. Za šta će nam to?

Ako unutar formata postoji znak %, printf će to da shvati kao naznaku kako da nastavi sa argumentima koji slede iza formata. Prva naznaka se odnosi na prvi argument nakon formata, druga naznaka se odnosi na sledeći argument, i tako redom. (iako postoji nekoliko izuzedata, ali o tom malo kasnije).

Kada se % nalazi u kombinaciji sa nekim drugim znakom (ili znakovima) to se ponekad naziva specifikator. U prethodnom primeru u formatu se nalazi jedan specifikator: %d.

Slovo d označava da bi se odgovarajući argument trebao tretirati kao vrednost tipa int i da na ekran bude poslat kao broj.

U nastavku ćemo dati samo neke od specifikatora:

%d

%d (kao decimalni broj) specifiicira da je njemu odgovarajući argument tipa int i da bi trebalo da bude predstavljeno kao ceo broj (engl. fixed-point decimal number); Najčešće se koristi za cele brojeve, iako postoji i sinonim %i (kao integer).

%x

%x (kao hexadecimal) specificira da je odgovarajući argument ceo broj koji treba da se prikaže kao ceo heksadecimalni broj.

%o

%o (kao octal) specificira da je odgovarajući argument ceo broj koji treba da se prikaže kao ceo oktalni broj.

%c

%c (kao char) specificira da je odgovarajući argument vrednost tipa int ili char i da bi trebalo da se prikaže kao znak (character).

%f

%f (kao float) specificira da je odgovarajući argument vrednost tipa float i da bi trebalo da se prikaže kao floating-point number (broj sa decimalnom tačkom, kao npr 4.5)

%%

S obzirom da se % koristi da bi se označio specifikator, da bi prikazali baš znak % treba da se napišu dva znaka jedan pored drugog (samo jedan će da bude prikazan)

Na primerima prikazano:

#include <stdio.h>
int main(void)

{

int VarInt;
char VarChar;
float VarFloat;
VarInt = 2018;
VarChar = 'r';
VarFloat = 3.1415;
printf("Godina je %d. Oznaka za poluprecnik je %c  dok je PI jednako %f", VarInt, VarChar, VarFloat);
return 0;

}

U ovom primeru printf funkcija radi sledeće:

  • analizira format i kako ne nailazi ni na kakav specifikator, na ekran ispisuje "Godina je ";
  • zatim printf nailazi na specifikator odakle se vidi da na tom mestu treba prikazati ceo broj; zbog toga se pristupa prvom argumentu nakon formata (promenljjiva VarInt) i na ekranu se prikazuje broj "2018";
  • printf nastavlja sa sadržajem formata i prikazuje string "Oznaka za poluprecnik je";
  • zatim nailazi na sledeći  specifikator; ovog puta se traži da program prokaže vrednost tipa char kao jedan karakter; pa se karakter preuzoma iz drugog argumenta posle formata (VarChar) i na ekranu se prikazuje karakter "r" ;
  • printf nastavlja sa obradom formata i prikazuje string "dok je PI jednako ";
  • sledeći (i poslednji) specifikator traži da se prikaže broj sa decimalnom tačkom (float), koji se preuzima iz trećeg argumenta nakon formata (VarFloat).


Kao rezultat svega toga, na ekranu će biti prikazano:

Godina je 2018. Oznaka za poluprecnik je r dok jre PI jednako 3.1415

 

Primer 2:

#include <stdio.h>
int main(void)

{

int i;

i = 31;

printf("%d %x %o",i,i,i);

return 0;

}

U ovom primeru format sadrži skoro samo specifikatore - tri komada. To znači da se za format trebaju isporučiti tri argumenta. U našem primeru, to je izvedeno tako što je ponovljeno ime iste promenljive tri puta. Kada se ovaj program izvrši, na ekranu će biti prikazana ista promenljiva (odnosno njena vrednost: 31) tri puta - jednom kao decimalni broj, jednom kao heksadecimalni broj i jednom kao oktalni broj.

Kao rezultat, na ekranu će biti prikazano:

31 1F 37

 

Greške (izbegavajte da uradite ovo):

Sada ćemo da prikažemo kakve se greške mogu napraviti i kakve su posledice tih grešaka. U nastavku su prikazane neke od tipičnih grešaka:

 

Greška 1 - navedeno je višespecifikatora u formatu nego što je navedeno argumenata:

printf("%d %d %d", i, j);

U ovom slučaju su navedena 3 specifikatora a samo dva argumenta - zadnjem specifikatoru nedostaje njegov argument. Većina modernih kompajlera će da se pobuni zbog ovoga. Međutim, neki od starijih kompajlera se neće buniti, ali kad se program pokrene, ono što će se dobiti nema nikakvog smisla.

 

Greška 2 - navedeno je manje specifikatora nego što je argumenata:

printf("%d", i, j);

Ako se kompajler ne pobuni, kompajliranje će biti izvršeno, program će moći da se izvrši, samo što se neće prikazati vrednost argumenta za koji nedostaje specifikator.

 

Greška 3 - tip koji je najavljen pomoću specifikatora se razlikuje od tipa odgovarajućeg argumenta:

int i;

i=100;

printf("%f",i);

Specifikator je tražio float ali je data promenljiva tipa int. Ako se kompajler ne pobuni, vrednost koja će biti prikazana na ekranu prilikom izvršenja programa neće biti ono što se očekuje. Pošto se u računaru promenljive tipa int i float čuvaju na različite načine, npr za int se koriste 32 bita a za float 64 bita, ako je potrebna float vrednost, a postavi se int promenljiva, uzet će se ono što je u tom delu memorije plus još deo iz memorije posle te int promenljive (float je u ovom slučaju duplo više bitova u memoriji).
 

Malo manje dramatičan primer:

ako vam je potreban int a obezbedili ste promenljivu tipa char:

char c;

c='?';

printf("%d",c);

Ništa loše se neće desiti. Ranije smo objašnjavali da se tip podataka char tretira kao mali ceo broj u mamoriji računara. Ako se pomoću specifikatora traži decimalni broj, a obezbedi promenljiva tipa char, printf će da prikaže ASCII kod onog karaktera koji je funkciji prosleđen kao argument.

 
***

Potrebno je da se obrati pažnja na sledeće:

String koji se prikazuje na ekranu od strane printf funkcije će da se prikazuje karakter po karakter i, ako se ne navede drugačije, ispuniće celu liniju, s kraja na kraj ekrana (ili prozora).

printf("Ovo je tekst br 1.); printf("Ovo je tekst br 2.);

printf("Ovo je tekst br 3.);

Ovo će biti prikazano u jednoj liniji (možda razvučeno u više od jedne linije) i prikazao kao:

Ovo je tekst br 1. Ovo je tekst br 2. Ovo je tekst br 3.

 

Na sledeći način se ispisuje tekst u više linija:

printf("Ovo je tekst br 1.\nOvo je tekst br 2.\n");
printf("\n
Ovo je tekst br 3.");

uovom slučaju će tekst na ekranu biti kao u nastavku:

 

Ovo je tekst br 1.
Ovo je tekst br 2.
Ovo je tekst br 3.