Унос и испис података

У програмском језику С операције уноса и исписа података реализују се помоћу улазно/излазних функција дефинисаних у програмској библиотеци stdio.h. У овој библиотеци дефинисано је много функција, а предмет ове лекције биће само функције scanf() и printf(). Остале функције за улаз/излаз обрађиваћемо касније.

Пошто програмски језик C потиче са UNIX система, он све уређаје третира као датотеке. Па тако и податке које требамо унети или исписати можемо посматрати као датотеке које садрже низове сукцесивних знакова који се називају токови (енгл. streams).

Најчешће се улазни подаци читају из тока stdin, излазни уписују у ток stdout, док се кодови грешака насталих при извршењу програма уписују у ток stderr. У општем случају извориште података за унос може бити тастатура, било који улазни уређај или датотека, док одредиште за испис може бити екран, штампач, било који излазни уређај или датотека.

Улазне и излазне коверзије

Код операције улаза, прво се идентификује кôд знака додељен притиснутом тастеру на тастатури, знак се исписује на екрану и бинарни кôд знака памти у меморији. Код излазних операција бинарни кôд знака запамћен у меморији, конвертује се у текстуални облик знака којег разумеју људи и исписује на екрану.

Функције scanf() и printf() обављају такозвани форматирани улаз и форматирани излаз, јер као аргументе користе низ знакова који управља описаним процесима конверзија при улазу/излазу података.

Место на коме се налази улазни или излазни податак назива се поље. Број знакова који се може сместити у неко поље назива се ширина поља. Формат одређује распоред и ширину поља у којем се налазе улазни или излазни подаци. Формат је низ знакова који може садржати наизменично делове текста, размаке и спецификаторе конверзија. Спецификатор конверзије прецизно одређује начин конверзије податка који се уноси или исписује. Спецификатор конверзије увек почиње знаком % и има општи облик:

%[опциони_елементи]симбол_конверзије

Излазна функција printf()

Функција printf() служи за излазну конверзију и испис података у стандардни излазни ток stdout. Најједноставнији општи облик функције printf() био би:

printf(формат,листа_аргумената);

где формат садржи делове текста, размаке и спецификаторе конверзије, а листа аргумената вредности података које ће бити конвертоване и исписане (обично идентификатори променљивих, константе или изрази).

Иако смо се са неким симболима конверзије већ сусретали обрађивајућу типове података, сада ћемо их све сагледати у једној табели:

Симбол Тип Опис
d или i int Означена декадна целобројна вредност
u unsigned int Неозначена декадна целобројна вредност
o unsigned int Неозначена октална целобројна вредност
x или X unsigned int Неозначена хексадекадна целобројна вредност
f или F double Реалан број
e или E double Реалан број у нотацији са експонентом и мантисом
g или G double Реалан број у скраћеном запису за %f или %e тј. %F или %E
a или A double Реалан хексадекадни број
c char Карактер (један знак)
s string Низ карактера (знакова)
p pointer Показивач
n Не штампа ништа, а његов аргумент мора да буде показивач на означену целобројну вредност у коју се записује број одштампаних карактера.
Прилично потпуну табелу можете пронаћи на: wikipedia

Општи облик спецификатора конверзије за функцију printf() је следећи:

%[параметри][ширина][.прецизност][дужина]симбол

Знак % и симбол конверзије (из табеле изнад) су обавезни елементи, док се између њих могу додатно навести, по датом редоследу и следећи необавезни елементи:

  • параметар означава да се излазна вредност поравна у излазном пољу улево (подразумевано је поравнање удесно и додавање размака с леве стране)
  • параметар + означава да се стави знак + испред позитивне вредности
  • параметар размак означава да испред означене вредности која нема ни + ни – треба оставити једно празно место
  • параметар # означава обавезно исписивање 0 за октални запис, знакова 0х или 0Х за хексадекадни запис и децималне тачке за реалне бројеве иако немају разломљени део броја
  • параметар 0 означава да се код бројчаних вредности, приликом поравнања удесно, са леве стране дописују нуле уместо размака.
  • ширина је целобројна вредност која задаје минималну ширину поља за испис, тј. укупан број позиција који заузима излазни податак (уз допуну размацима са леве стране). Уколико је за приказ излазне вредности потребно више позиција, поље се аутоматски проширује за потребан број места.
  • .прецизност је целобројна вредност која задаје број децимала реалног броја.
  • дужина: Слово h испред симбола конверзије d, i, u, o, x и X означава да се ради о кратком (short) целобројном податку, слово l испред симбола конверзије d, i, u, o, x и X означава да се ради о дугом (long) целобројном податку, слово L испред симбола конверзије f, F, a, A, e, E, g, G и значи да се ради о реалном податку типа long double.

Уместо величине тј. минималне ширине поља може се ставити знак * након чега се вредност за минималну ширину поља наводи у листи аргумената функције printf() који мора бити типа int и претходити идентификатору променљиве која се исписује. Исто важи и за прецизност.

Улазна функција scanf()

Функција scanf() служи за улазну конверзију и упис података у стандардни улазни ток stdin. Најједноставнији општи облик функције scanf() био би:

scanf(формат,листа_аргумената);

Формат задаје врсте конверзија које се обављају при улазу, а лису аргумената чине адресе променљивих у које се уносе учитани и конвертовани подаци. Адреса променљиве формира се постављањем знака & испред идентификатора променљиве.

Спецификатор Тип
c Један знак
d Декадни цео број
i Цео број, декадни, или октални ако је почет са 0, или хексадекадни ако је почет са 0х
u Неозначен цео број
o Октални цео број
x Хексадекадни цео број
e, f, g Реалан број
p Показивач
s Низ знакова
Слово h испред симбола конверзије d, i, u, o, x и X означава да се ради о кратком (short) податку, a слово l да се ради о дугом (long) податку.

Општи облик спецификатора конверзије за функцију scanf() је следећи:

%[*][величина]спецификатор

где * означава прескок додељивања, а величина целобројну вредност која задаје максималну ширину улазног поља.


Пример 1: Напишите програм који врши конверзију унете раздаљине у миљама у раздаљину у километрима.

#include <stdio.h>
main()
{
	float m, k;
	printf("Unesite razdaljinu u miljama: ");
	scanf("%f", &m);
	k = m * 1.609;
	printf("Razdaljina %f u miljama = %f u kilometrima\n", m, k);
}

Резултат извршавања овог програма:

Unesite razdaljinu u miljama: 5
Razdaljina 5.000000 u miljama = 8.045000 u kilometrima

Press any key to close this window . . .

Пример 2. Преправите претходни програм тако да се бројеви исписују на следећи начин:

  • Приликом исписа све бројеве приказати као бројеве са 3 децимална места.
  • Приликом исписа испред сваког броја мора да стоји знак – ако је број негативан, односно + ако је позитиван.
#include <stdio.h>
main()
{
	float m, k;
	printf("Unesite razdaljinu u miljama: ");
	scanf("%f", &m);
	k = m * 1.609;
	printf("Razdaljina %+.3f u miljama = %+.3f u kilometrima\n", m, k);
}

Задатак. Петар је решио да уштеди новац за бољу графичку картицу сакупљајући кусур из самопослуге и то кованице од 1, 2, 5, 10 и 20 динара. С времена на време преброји колико има којих кованица и израчуна колико му новца недостаје до 12000 динара. Помозите Петру у рачуну тако што ћете му направити програм који даје следећи излаз:

Koliko imas kovanica od 1 dinar: 245
Koliko imas kovanica od 2 dinara: 287
Koliko imas kovanica od 5 dinara: 197
Koliko imas kovanica od 10 dinara: 142
Koliko imas kovanica od 20 dinara: 87

Uneo si sledece:
1                2               5               10              20
245              287             197             142             87

Sakupio si ukupno 4964 dinara.
Nedostaje ti jos 7036 dinara.

Press any key to close this window . . .

Неовлашћено коришћење ових садржаја, без претходне писмене сагласности аутора, сматра се кршењем Закона о ауторским и сродним правима!