Sunteți pe pagina 1din 10

Modul 3 Funcii de intrare/ieire n limbajul C

Funcii de intrare/ieire n C
Funcii de citire/scriere pentru caractere i iruri de caractere
Funcii de citire/scriere cu format
Funcia printf
Funcia scanf
Observaii
Fluxuri de intrare/ieire in C++

Funcii de intrare/ieire n C
n limbajul C, nu exist instruciuni de intrare/ieire (citire/scriere), tocmai pentru a mri
portabilitatea limbajului. Pentru a realiza citiri i scrieri se apeleaz funcii de intrare/ieire
din bibliotecile mediului de programare.
Pentru operaii de citire a datelor iniiale i de afiare a rezultatelor sunt definite funcii
standard, declarate n fiierul antet stdio.h. Se vor prezenta i funciile de intrare/ieire
nestandard cele mai uzuale, avnd prototipul in conio.h. Utilizarea acestor funcii ntr-un
program, va presupune deci, includerea respectivelor fiiere antet.
Aici vom prezenta numai acele funcii folosite pentru citire de la tastatur i pentru afiare
pe ecran, deci pentru lucru cu fiierele standard numite stdin i stdout. Fiierele standard
stdin i stdout sunt fiiere text. Un fiier text este un fiier care conine numai caractere
ASCII grupate n linii (de lungimi diferite), fiecare linie terminat cu un terminator de linie
format din unul sau dou caractere. n sistemele Windows se folosesc dou caractere ca
terminator de linie: \n i \r, adic newline (trecere la linie nou) i return (trecere la nceput
de linie). n sistemele Unix/Linux se folosete numai caracterul \n (newline) ca terminator de
linie, caracter generat de tasta Enter.
Funciile I/O ( Input/Output - intrare/ieire ) din C pot fi grupate n cteva familii:
Funcii de citire/scriere caractere individuale: getchar, putchar, getch, putch;
Funcii de citire/scriere linii de text: gets, puts;
Funcii de citire/scriere cu format (cu conversie): scanf, printf.
Funcii de citire/scriere pentru caractere i iruri de caractere
Pentru operaiile I/O la nivel de caracter:
int getchar ();
int putchar (int c);
int getche ();
int getch ();
int putch (int c);

Pentru operaii I/O cu iruri de caractere:


char * gets(char * s);
int puts(const char * ir);
Tabelul urmtor conine o descriere detaliat a funciilor pentru operaiile I/O la nivel de
caracter:

Funcie

Exemple

Descriere

Rezultat

int getchar();

char c;
c=getchar();

Citete un caracter

Returneaz codul unui


caracter citit de la
tastatura sau valoarea
EOF (End Of File constant
simbolic
definit n stdio.h, avnd
valoarea -1) dac s-a
tastat Ctrl+Z.
Returneaz
codul
caracterului sau EOF n
cazul unei erori.
Returneaz
EOF
la
tastarea
lui
Ctrl+Z,
respectiv CR ( \r, cu codul
13) la tastarea lui Enter.

int putchar(int char c;


putchar(c);
c);
int getche();

char c;
c=getche();

int getch();

char c;
c=getch();

int putch(int c);

char c;
putch(c);

Tiprete pe ecran
transmis ca parametru

caracterul

Citete un caracter (ateapt


apsarea unei taste, chiar dac n
buffer-ul de intrare mai sunt
caractere neprelucrate) i afieaz
caracterul pe ecran
Analog cu funcia de mai sus, dar
caracterul nu se transmite n ecou
(nu se afieaz pe ecran).
Tiprete pe ecran caracterul Returneaz
codul
transmis ca parametru
caracterului sau EOF n
cazul unei erori.

Funciile getch, putch, getche nu sunt standard, de aceea este bine s se evite utilizarea lor!
Tabelul urmtor conine o descriere detaliat a funciilor pentru operaiile I/O cu iruri de
caractere:

Funcie

Exemple
utilizare

Descriere

Rezultat

char * gets(char * s);

char sir[10];
gets(sir);

Returneaz
adresa
primului caracter din ir.
Dac se tasteaz CTRL+Z
returneaz NULL.

int puts(const char * s);

char sir[10];
puts(sir);

Citete caractere pn la
ntlnirea lui Enter; acesta
nu se adaug la irul s.
Plaseaz /0 la sfritul lui s.
Obs: codul lui Enter e scos
din buffer-ul de intrare.
Tiprete irul primit ca
parametru, apoi NewLine,
cursorul
trecnd
la
nceputul rndului urmtor

Returneaz codul ultimului


caracter din ir sau EOF la
insucces

Funcii de citire/scriere cu format


Funciile scanf i printf permit citirea cu format i respectiv scrierea cu format pentru orice
tip de date. Antetul i descrierea acestor funcii sunt:
int printf ( format, arg1, arg2, ... );
afieaz pe ecran valorile expresiilor din lista argumentelor, conform formatului
specificat;
argumentele pot fi constante, variabile, expresii
dac nu apare nici un argument, pe ecran se tipresc doar caracterele din irul
format.
formatul este un ir de caractere care trebuie s includ cte un descriptor de format
pentru fiecare din argumente.
caracterele din format care nu fac parte din descriptori se tipresc pe ecran.
Returneaz numrul de valori tiprite sau EOF n cazul unei erori.

int scanf ( format, adr1, adr2, ... );


Citete informaiile tastate pe care le interpreteaz conform specificatorilor din format,
memornd valorile citite la adresele transmise ca parametri.
Formatul este un ir de caractere care trebuie s includ cte un descriptor de format
pentru fiecare dintre valorile citite.
Adresele sunt pointeri sau adresele variabilelor ale cror valori se citesc;
Adresa unei variabile se obine folosind operatorul de adresare &, astfel:
&nume_variabila
Valorile ntregi sau reale consecutive introduse de la tastatur trebuie separate
de cel puin un spaiu alb (enter, spaiu, tab)
Returneaz numrul de valori citite sau EOF dac s-a tastat Ctrl/Z.

Funcia printf
Descriptorii de format admii n funcia printf sunt:

Specificatori format

Descriere

%d

ntreg zecimal cu semn

%i

ntreg zecimal, octal (0) sau hexazecimal (0x, 0X)

%o

ntreg n octal, fr 0 la inceput

%u

ntreg zecimal fr semn

%x, %X

ntreg hexazecimal, fr 0x/0X; cu a-f pt. %x, A-F pt. %X

%c

caracter

%s

ir de caractere, pn la '\0' sau nr. de caractere dat ca precizie

%f, %F

real fr exp.; precizie implicit 6 poz.; la precizie 0: fr punct


real (posibil cu exponent)

%e, %E

numere reale cu mantis i exponent (al lui 10); precizie implicit


6 poz.; la precizie 0: fr punct

%g, %G

numere reale n format %f sau %e, funcie de valoare real, ca %e,


%E dac exp. < -4 sau precizia; altfel ca %f. Nu tiprete zerouri
sau punct zecimal n mod inutil

%p

pointer, n formatul tiprit de printf

%ld, %li

numere ntregi lungi

%lf, %le, %lg

numere reale n precizie dubl (double)

%Lf, %Le, %Lg

numere reale de tip long double

%%

caracterul procent

Exemple de utilizare printf:


printf ("\n");
printf ("\n Eroare \n");

// trecere la o noua linie


// scrie Eroare pe o linie nou

int a=3;
printf ("%d\n",a);
// scrie 3 ca ntreg i trece la linia urmtoare
int a=5, b=7;
printf ("a=%d b=%d\n", a, b);
//scrie a=5 b=7 i trece la linia urmtoare
int g=30, m=5, s=2;
printf ("%2d grade %2d min %2d sec\n", g,m,s);
// scrie 30 grade 5 min
2 sec i schimba linia
int anInt = 12345;
float aFloat = 55.6677;
double aDouble = 11.2233;
char aChar = 'a';
char aStr[] = "Hello";
printf("The
printf("The
printf("The
printf("The
printf("The

int is %d.\n", anInt);


float is %f.\n", aFloat);
double is %f.\n", aDouble);
char is %c.\n", aChar);
string is %s.\n", aStr);

//The
//The
//The
//The
//The

int is 12345.
float is 55.667702.
double is 11.223300.
char is a.
string is Hello.

printf("The int (in hex) is %x.\n", anInt);


//The int (in hex) is 3039.
printf("The double (in scientic) is %e.\n", aDouble);
//The double (in scientic) is 1.122330e+01.
printf("The float (in scientic) is %E.\n", aFloat);
//The float (in scientic) is 5.566770E+01.

Programatorul trebuie s asigure concordana dintre descriptorii de format i tipul


variabilelor sau expresiilor care urmeaz argumentului, deoarece funciile scanf i printf nu
fac nici o verificare i nu semnaleaz neconcordane. Exemplele urmtoare trec de
compilare dar afieaz incorect valorile variabilelor:
int i=3;
float f=3.14;
printf ("%f \n", i);
printf ("%i \n", f);

// scrie 0.00 (n Dev-Cpp)


// scrie 1610612736 (Dev-Cpp)

Funciile scanf i printf folosesc noiunea de cmp (field): un cmp conine o valoare i este
separat de alte cmpuri prin spaii albe. Fiecare descriptor de format poate conine
mrimea cmpului, ca numr ntreg. Aceast mrime se folosete mai ales la afiare, pentru
afiare numere pe coloane, aliniate la dreapta. n lipsa acestei informaii mrimea cmpului
rezult din valoarea afiat.
Exemple:
printf("%d %d",a,b);
printf("%8d8%d",a,b);

// 2 campuri separate prin blanc


// 2 cmpuri de cate 8 caractere

int number = 123456;


printf("number=%d.\n", number);
//number=123456.
printf("number=%8d.\n", number);
//number= 123456.
printf("number=%3d.\n", number);
//number=123456.
double value = 123.14159265;
printf("value=%f;\n", value);
//value=123.141593;
printf("value=%6.2f;\n", value);
//value=123.14;
printf("value=%9.4f;\n", value);
//value= 123.1416;
printf("value=%3.2f;\n", value);
//value=123.14;

// Dim camp prea mica.E ignorata.

// Dim camp prea mica.E ignorata.

Dac nu se precizeaz mrimea cmpului i numrul de cifre de la partea fracionar pentru


numere, atunci funcia printf alege automat aceste valori:
dimensiunea cmpului rezult din numrul de caractere necesar pentru afiarea
cifrelor, semnului i altor caractere cerute de format;
numrul de cifre de la partea fracionar este 6 indiferent dac numerele sunt de tip
float sau double sau long double, dac nu este precizat explicit.
Se poate preciza numai mrimea cmpului sau numai numrul de cifre la partea fracionar.
Exemple:
float a=1.; double b=0.0002; long double c=7.5; float d=-12.34;
printf ("%.0f %20lf %20.10Lf %f \n", a, b, c, d);

Specificnd dimensiunea cmpului n care se afieaz o valoare, putem realiza scrierea mai
multor valori n coloane. Dac valoarea de afiat necesit mai puine caractere dect este
mrimea cmpului, atunci aceast valoare este aliniat la dreapta n cmpul respectiv.
Secvena urmtoare va scrie trei linii, iar numerele afiate vor apare ntr-o coloan cu cifrele
de aceeai pondere aliniate unele sub altele:
int a=203, b=5, c=16;
printf (%10d \n %10d \n %10d \n,a,b,c);

Formatul cu exponent (%e) este util pentru numere foarte mari, foarte mici sau despre ale
cror valori nu se tie nimic. Numrul este scris cu o mantis fracionar (ntre 0 i 10) i un
exponent al lui 10, dup litera E (e).
La formatul %g printf alege ntre formatul %f sau %e n funcie de ordinul de mrime
al numrului afiat: pentru numere foarte mari sau foarte mici formatul cu exponent, iar
pentru celelalte formatul cu parte ntreag i parte fracionar.
ntre caracterul % i literele care desemneaz tipul valorilor scrise mai pot apare, n ordine:
a) un caracter ce exprim anumite opiuni de scriere:
- (minus): aliniere la stnga n cmpul de lungime specificat
+ (plus): se afieaz i semnul + pentru numere pozitive
0 : numerele se completeaz la stnga cu zerouri pe lungimea w
# : form alternativ de scriere pentru numere
b)
un numr ntreg w ce arat lungimea cmpului pe care se scrie o valoare, sau
caracterul * dac lungimea cmpului se d ntr-o variabil de tip int care precede variabila
a crei valoare se scrie.
c) punct urmat de un ntreg, care arat precizia (numrul de cifre de dup punctul zecimal) cu
care se scriu numerele nentregi.
d) una din literele h, l sau L care modific lungimea tipului numeric.

/* Exemplu de utilizare a opiunii 0 pentru a scrie ntotdeauna dou


cifre, chiar i pentru numere de o singur cifr: */
int ora=9, min=7, sec=30;
printf ("%02d:%02d:%02d\n",ora, min, sec); // scrie 09:07:30
//Exemplu ce afiseaza 10 spatii
printf(afisez 10 spatii: %*c,10, );
// Exemplu de utilizare a opiunii - pentru aliniere iruri la stnga:
char a[] = "unu", b[] ="cinci", c[]= "sapte" ;
printf (" %-10s \n %-10s \n %-10s \n", a, b, c);
int i1 = 12345, i2 = 678;
printf("Hello, first int is %d, second int is %5d.\n", i1, i2);
//Hello, first int is 12345, second int is
678.
printf("Hello, first int is %d, second int is %-5d.\n", i1, i2);
//Hello, first int is 12345, second int is 678 .

char msg[] = "Hello";


printf("xx%10sxx\n", msg);
printf("xx%-10sxx\n", msg);

//xx
Helloxx
//xxHello
xx

n general trebuie s existe o concordan ntre numrul i tipul variabilelor i formatul de


citire sau scriere din funciile scanf i printf, dar aceast concordan nu poate fi verificat
de compilator i nici nu este semnalat ca eroare la execuie, dar se manifest prin
falsificarea valorilor citite sau scrise. O excepie notabil de la aceast regul general este
posibilitatea de a citi sau scrie corect numere de tip double cu formatul %f (pentru tipul
float), dar nu i numere de tip long double (din cauza diferenelor de reprezentare intern a
exponentului).
Funcia scanf
Descriptorii de format admii n funcia scanf sunt:

Specificatori format

Descriere

%d

ntreg zecimal cu semn

%i

ntreg zecimal, octal (0) sau hexazecimal (0x, 0X)

%o

ntreg n octal, precedat sau nu de 0

%u

ntreg zecimal fr semn

%x, %X

ntreg hexazecimal, precedat sau nu de 0x, 0X

%c

orice caracter; nu sare peste spaii (doar " %c")

%s

ir de caractere, pn la primul spaiu alb. Se adaug '\0'.

%e, %E, %f, %F, %g, %G,


%a, %A
%p

real (posibil cu exponent)

%ld, %li

numere ntregi lungi

%lf

numere reale n precizie dubl (double)

%Lf

numere reale de tip long double

%*+

ir de caractere din mulimea indicat ntre paranteze

%*^+

ir de caractere exceptnd mulimea indicat ntre paranteze

%%

caracterul procent

pointer, n formatul tiprit de printf

Dup cum spuneam mai sus, argumentele funciei scanf sunt de tip pointer i conin
adresele unde se memoreaz valorile citite. Pentru variabile numerice aceste adrese se
obin cu operatorul de adresare (&) aplicat variabilei care primete valoarea citit.
Numerele citite cu scanf pot fi introduse pe linii separate sau n aceeai linie dar separate
prin spaii albe sau caractere Tab. ntre numere succesive pot fi oricte caractere separator
(\n,\t, ). Un numr se termin la primul caracter care nu poate apare ntr-un numr.
Exemple:

int n, a,b;
scanf("%d", &n);
scanf("%d%d", &a,&b);
float rad;
scanf("%f", &rad);
char c;
scanf("%c", &c);

// citete un ntreg n variabila n


// citete doi ntregi in a i b
// citete un numar real in rad
// citete un caracter in c

// program test scanf


#include <stdio.h>
int main() {
int anInt;
float aFloat;
double aDouble;
printf("Introduceti un int: "); // Mesaj afisat
scanf("%d", &anInt);
// citete un ntreg n variabila anInt
printf("Valoarea introdusa este %d.\n", anInt);
printf("Introduceti un float: ");// Mesaj afisat
scanf("%f", &aFloat);
// citete un float n variabila aFloat
printf("Valoarea introdusa este %f.\n", aFloat);
printf("Introduceti un double: ");// Mesaj afisat
scanf("%lf", &aDouble);
// citete un ntreg n variabila aDouble
printf("Valoarea introdusa este %lf.\n", aDouble);
return 0;

La citirea de iruri trebuie folosit un vector de caractere, iar n funcia scanf se folosete
numele vectorului (echivalent cu un pointer). Exemplu:
char s[100];
scanf(%s, s);

//uneori funcioneaz dar este greit:

scanf(%s, &s);

Chiar i spaiile trebuie folosite cu atenie n irul format din scanf. Exemplu de citire care
poate crea probleme la execuie din cauza blancului din format:
scanf("%d

",&a);

// corect este

scanf (%d,&a);

Funcia scanf nu poate afia nimic, iar pentru a precede introducerea de date de un mesaj
trebuie folosit secvena printf, scanf. Exemplu:
printf ("n= ");
scanf ("%d", &n);

// NU: scanf(n=%d, &n);

De reinut diferena de utilizare a funciilor scanf i printf!


Exemplu:

scanf("%d%d", &a, &b);


printf("%d %d", a, b);

// citete dou numere ntregi n a i b


// scrie valorile din a i b separate de un spaiu

Alte exemple de utilizare a funciilor scanf i printf:


int i;
float f;
double d;
scanf("%d%f%lf",&i, &f, &d); //citeste un intreg, un real si un double
char c;
printf("Rezultatul este: %c\n",c); //afiseaza un mesaj si un character
float a;
double b;
scanf(%f, &a);
printf(%5.2f,a);
scanf(%lf, &b);
printf(%-4.2lf,b);
printf(%+4.2lf,b);

//
//
//
//
//

citire variabila float


sunt afisate minim 5 caractere, maxim 2 zecimale
citire variabila double
afisare cu aliniere stanga
afisare cu adaugare semn (+,-)

Observaii
Toate funciile de citire menionate (excepie getch, getche) folosesc o zon tampon (buffer)
n care se adun caracterele tastate pn la apsarea tastei Enter, moment n care
coninutul zonei buffer este transmis programului. n acest fel este posibil corectarea unor
caractere introduse greit nainte de apsarea tastei Enter.
Caracterul \n este prezent n zona buffer numai la funciile getchar i scanf, dar funcia gets
nlocuiete acest caracter cu un octet zero, ca terminator de ir n memorie (rezultatul
funciei gets este un ir terminat cu zero).
Funcia scanf recunoate n zona buffer unul sau mai multe cmpuri (fields), separate i
terminate prin caractere spaiu alb (blanc, \n, \r,\f); drept consecin, preluarea de
caractere din buffer se oprete la primul spaiu alb, care poate fi i caracterul terminator de
linie. Urmtorul apel al funciei getchar sau scanf se uit n zona buffer dac mai sunt
caractere, nainte de a atepta introducerea de la taste i va gsi caracterul terminator de
linie rmas de la citirea anterioar.
Pentru ca un program s citeasc corect un singur caracter de la tastatur avem mai multe
soluii:
apelarea funciei fflush(stdin) nainte de oricare citire; aceast funcie golete zona buffer
asociat tastaturii i este singura posibilitate de acces la aceast zon tampon.
introducerea unei citiri false care s preia terminatorul de linie din buffer (cu getchar(),
de exemplu).
utilizarea funciei nestandard getch (declarat n conio.h), funcie care nu folosete o
zon buffer la citire
citirea unui singur caracter ca un ir de lungime 1:
char c[2];
scanf (%1s,c);

// memorie ptr un caracter i pentru terminator de ir


// citete ir de lungime 1

Unele medii integrate nchid automat fereastra n care se afieaz rezultatele unui program.
Pentru meninerea rezultatelor pe ecran vom folosi fie o citire fals (pune programul n
ateptare) fie instruciunea: system(pause); din stdlib.h.
Fluxuri de intrare/ieire in C++
n C++ s-a introdus o alt posibilitate de exprimare a operaiilor de citire-scriere, pe lng
funciile standard de intrare-ieire din limbajul C. n acest scop se folosesc cteva clase
predefinite pentru fluxuri de I/O (declarate n fiierele antet iostream.h i fstream.h).
Un flux de date (stream) este un obiect care conine datele i metodele necesare operaiilor
cu acel flux. Pentru operaii de I/O la consol sunt definite variabile de tip flux, numite cin
(console input) respectiv cout (console output).
Operaiile de citire sau scriere cu un flux pot fi exprimate prin metode ale claselor flux sau
prin doi operatori cu rol de extractor din flux (>>) sau insertor n flux (<<). Atunci cnd
primul operand este de un tip flux, interpretarea acestor operatori nu mai este cea de
deplasare binar ci este extragerea de date din flux (>>) sau introducerea de date n flux
(<<).
Operatorii << i >> implic o conversie automat a datelor ntre forma intern (binar) i
forma extern (ir de caractere). Formatul de conversie poate fi controlat prin cuvinte cheie
cu rol de "modificator".
Exemplu de scriere i citire cu format implicit:
#include <iostream.h>
void main ( ) {
int n; char s[20];
cout << " n= "; cin >> n;
cout << " un ir: "; cin >> s;
}

cout << s << "\n";

ntr-o expresie ce conine operatorul << primul operand trebuie s fie cout (sau o alt
variabil de un tip ostream), iar al doilea operand poate s fie de orice tip aritmetic sau de
tip char* pentru afiarea irurilor de caractere. Rezultatul expresiei fiind de tipul primului
operand, este posibil o expresie cu mai muli operanzi (ca la atribuirea multipl).
Exemplu:
cout << "x= " << x << "\n";

n mod similar, ntr-o expresie ce conine operatori >> primul operand trebuie s fie cin sau
de un alt tip istream, iar ceilali operanzi pot fi de orice tip aritmetic sau pointer la caractere.
Exemplu:
cin >> x >> y;

Este posibil i un control al formatului de scriere prin utilizarea unor modificatori, ns nu


vom detalia aici caest aspect, deoarece nu vom folosi aceste faciliti care in de C++, ele
fiind date doar ca titlu informativ.

S-ar putea să vă placă și