Facilitatile de I/O nu sint parte a limbajului C de aceea le-am introdus intr-un capitol separat. Nici un program real nu interactioneza cu mediul intr-un md mai complicat decit am prezentat pina acum. In acest capitol vom descrie biblioteca standard de I/O, care este un set de functii ce permit I/O standard pentru programele C. Functiile au menirea de a prezenta o interfata programabila convenabila, care sa permita operatiile prevazute de acele mai multe sisteme moderne de operare. Rutinele de I/O sint destul de eficinte incit foarte rar programatorul simte nevoia de a le ocoli chiar pentru aplicatii critice. In sfirsit, rutinele sint facute pentru a fi "0ortabile"
in sensul ca ele exista intr-o forma compatibila pentru orice sistem unde C exista si ca programele care utilizeaza biblioteca standard de I/O pot fi mutate de pe un sistem pe altul fara modificari. v3q14qv
Nu vom incerca sa descriem aici intreaga biblioteca de
I/O; sintem mai interesati de a arata esentialul despre scrierea programelor C in interactiune cu sistemul lor de operare.
7.1 Accesul la biblioteca standard
Fiecare fisier sursa care refera functiile bibliotecii standard trebuie sa contina linia
#include <stdio.h> aproape de inceput. Fisierul stdio.h defineste unele macrouri si variabile folosite de biblioteca I/O. Folosirea semnelor < si> in loc de obisnuitele ghilimele duble indreapta compilatorul sa caute fisierul intr-un director continind informatiile de eticheta standard (pentru UNIX tipic
|usr|include).
Mai departe, ar putea fi necesar ca atunci cind incarca programul sa se specifice biblioteca in mod explicit; de exemplu pentru PDP-11 UNIX, comanda pentru compilarea unui program ar fi cc source files, etc-ls unde -ls indica incarcarea din biblioteca standard (Caracterul l este litera el).
7.2. Intrari si iesiri standard-getchar si putchar
Mecanismul cel mai simplu de intrare este de a citi un caracter la un moment dat de la "standard input", care in general este terminalul utilizatorului, cu getchar. getchar() returneaza urmatorul caracter de intrare de cite ori este apelat. In cele mai multe medii care suporta C, un fisier poate fi substituit terminalului utilizind conventia <; daca un program "prog" foloseste getchar, atunci linia de comanda: prog<infile determina "prog" sa citeasca "infile" in loc de terminal.
Comutarea intrarii este facuta de o astfel de maniera incit
"prog" insusi nu simte aceasta; in particular, sirul "<infile>"
nu este inclus in argumentele "argv" ale liniei de comanda.
Comutarea intrarii este asadar invizibila daca intrarea vine de la un alt program via un "pipe mecanisme", linia de comanda otherprogr|prog executa ambele programe "otherprogr" si "progr" si aranjeaza
astfel ca intrarea standard pentru "progr" vine de la iesirea standard a lui "otherprogr".
"getchar" returneza valoarea EOF cind intilneste sfirsitul fisierului indiferent de ce este citit la intrare.
Biblioteca standard defineste constanta simbolica EOF ca fiind 1 ( cu un #define in fisierul stdio.h) dar testele se fac cu EOF nu cu -1, astfel ca sa fie independent de valoarea specifica.
Pentru iesire, putchar(c) pune caracterul c la iesirea standard care este terminalul. Iesirea poate fi directata spre un fisier folosind ">" daca "progr" utilizeaza putchar,
prog>aufile iesirea standard va fi "outfile" in loc de terminal. In sistemul
UNIX se poate utiliza o comunicatie (pipe) spre alt program: progr|anotherprogr comuta iesirea standard a programului "progr" ca intrare standard
a programului "anotherprogr". Si in aceste cazuri "progr"
nu are cunostiinta de redirectare.
Un numar destul de mare de programe au un singur sir de date ca intrare si un singur sir ca iesire; pentru astfel de programe I/O cu getchar putchar si printf pot fi in intregime adecvate, mai ales daca folosim facilitatile de redirectare si pipe pentru conectarea iesirii unui program cu intrarea altuia. De exemplu sa consideram programul "lower":
#include <stdio.h> main() /* convert input to lower case */
A int c;
while((c=getchar())!=EOF) putchar(isupper(c)?tolower(c):c);
S
Functiile "isupper" si "tolower" sint de fapt macrouri definite in stdio.h. Macrourile "isupper" testeaza care din argumentele sale este o litera mare, returnind in acest caz o valoare non-zero, sau o litera mica returnind in acest caz zero.
Macroul tolower converteste o litera mare in una mica. Indiferent de cum aceste functii sint implementate pe diferite masini, mediul lor extern este acelasi, astfel ca prgramele sint scutite de cunoasterea setului de caractere.
Pentru convertirea unor fisiere multiple se poate folosi un program la fel ca utilitarul "cat" din UNIX pentru colectarea fisierelor: cat file1file2...|lower>output si aceasta ne permite sa invatam cum se acceseaza fisierele dintr-un program. ("cat" este prezentat mai tirziu in acest capitol).
In biblioteca standard I/O functiile getchar si putchar pot de fapt sa fie macrouri, si aceasta permite ca sa nu fie apelata o functie pentru fiecare caracter(overhead). Vom arata aceasta in capitolul 8.
7.3. Iesirea formatata-printf
Cele doua rutine "printf" pentru iesire si scanf pentru intrare permit translatarea in si din reprezentarea caracterelor a cantitatilor numerice. Ele de asemenea permit generarea sau interpretarea liniilor formatate. Am folosit deja "printf" in capitolele precedente ; aici ii dam o descriere mai precisa si complecta. printf(control, arg1, arg2,....) printf converteste, formateaza si tipareste argumentele sale la iesirea standard sub controlul sirului "control". Sirul de control contine doua tipuri de obiecte: caractere ordinare, care sint simplu copiate in sirul de iesire si semnificatii de conversie dintre care fiecare cauzeaza conversia si tiparirea a urmatoarelor argumente succesive ale printf.
Fiecare specificatie de conversie este introdusa prin caracterul % si incheiata printr-un caracter de conversie. Intre % si caracterul de conversie pot fi:
Un semn minus care specifica cadrarea la stinga in cimp a argumentului convertit.
Un sir de digiti care specifica o lungime minima a cimpului. Numarul convertit va fi introdus in cimp la cel putin aceasta lungime sau mai mare daca este necesr. Daca argumentul are mai putine caractere decit dimensiunea cimpului el va fi cadrat la dreapta sau la stinga (in funcite de specificatie sau implicit) si va fi completatcu zero sau spatii pina la lungimea cimpului. Caracterul de complectare este normal blank, iar daca dimensiunea cimpului a fost specificata prin "leading" zero, este zero (aceasta nu implica cimpurile octale).
O virgula, care separa lungimea cimpului de un alt sir de digiti.
Un sir de digiti (precizia), care specifica numarul maxim de caractere acceptate dintr-un sir, sau numarul de pozitii dupa virgula zecimala virgula flotanta si dubla precizie.
Caracterele de conversie si semnificatiile lor sint: d-argumentul este convertit in zecimal o-argumentul este convertit in octal fara semn x-argumentul este convertit in hexazecimal fara semn u-argumentul este convertit in zecimal fara semn c-argumentul este preluat ca un singur caracter s-argumentul este un sir ;caracterele din sir sint introduse pina cind este intilnit caracterul nul sau pina cind este atinsa lungimea specificata. e-argumentul este luat ca virgula flotanta sau dubla precizie si convertit in notatia zecimala de forma a-im. nnnnnnEa+sau-iXX unde lungimea sirului de n-uri este specificata de precizie.
Precizia implicita este 6. f-argumentul este luat ca virgula mobila sau dubla precizie si convertit tot intr-o notatie zecimala de forma a-immm. nnnnnn unde lungimea sirului de n-uri este specificat de precizie, implicit este 6. De observat ca precizia nu determina numarul de digiti semnificativi in formatul f. g-foloseste % sau %l , oricare este mai scurt ; zerourile nesemnificative nu apar. Daca caracterul de dupa % nu este un caracter de conversie acest caracter este tiparit chiar 5 poate fi tiparit prin %%.
Cele mai multe formate de conversie sint evidente si au fost ilustrate in capitolele precedente. oO exceptie este precizia referitoare la siruri. Tabela urmatoare arata efectele unei varietati de specificatii asupra sirului "hello, world" de 12 caractere. Am pus doua puncte pentru a putea urmari mai bine lungimea.
::%10s: :hello, world:
:5-10s: :hello, world:
:%20s: : hello, world:
:%-20s: :hello, world :
:%20. 10s: : hello, wor:
:%-20. 10 :hello, wor :
:%. 10s: :hello, wor:
Atentiune: "printf" foloseste primul sau argument pentru a decide cite argumente urmeaza si de ce tip. Daca nu sint destule argumente sau de tip gresit veti obtine rezultate lipsite de sens.
Exercitiul 7.1 Scrieti un program care tipareste diferentiat o intrare arbitrara. Ca o conditie minima trebuie sa tipareasca caracterele non-grafice in octal sau hexa(conform uzantelor locale).
7.4. Intrarea formatata-scanf
Functia scanf este intrarea analog printf-iesirea, admitind aceleasi conversii in sens invers. scanf(control, arg1, arg2,...)
scanf citeste caractere de la intrarea standard, le interpreteaza conform formatului specificat in "control" si memoreaza rezultatele in celelalte argumente, care sint pointere ce indica unde vor fi depuse datele convertite.
Sirul de "control" contine de obiecei specificatii de conversie, care sint utilizate pentru o interpretare directa a secventelor de intrare. Sirul de control poate sa contina:
-blancuri, taburi, newlines" care sint ignorate (sint numite "caractere albe")
-caractere ordinare (nu%)
-specificatii de conversie continind caracterul % si optional caracterul de suprimare, un numar optional de specificare a lungimii maxime a cimpului si un caracter de conversie
O specificatie de conversie determina conversia urmatorului cimp de intrare. Normal rezultatul este plasat in variabila pointata de argumentul corespunzator. Daca se indica suprimarea prin caracterul * oricum cimpul de la intrare este ignorat 9se sare peste el) si nu se face nici o retinere de spatiu. Un cimp de la intrare este definit ca un sir de non "caracter alb " fie pina la lungimea specificata a cimpului.
Caracterul de conversie indica interpretarea cimpului de la intrare argumentul corespunzator trebuie sa fie un pointer asa cum este cerut de semantica "C" limbajului "C". Urmatoarele
caractere de conversie sint legale: d-un intreg zecimal este asteptat la intrare ;argumentul corespunzator trebuie sa nu fie pointer intreg. o-un intrteg octal este asteptat la intrare ;argumentul corespunzator trebuie sa fie un pointer de intreg. x-un intreg hexazecimal este asteptat la intrare ; argumentul corespunzator trebuie sa fie un pointer de intreg. h-un intreg "short" este asteptat la intrare: argumentul trebuie sa fie un pointer de intreg "short" ("scurt"). c-un singur caracter este asteptat ; argumentul corespunzator trebuie sa fie un piinter de caracter. In acest caz ignorarea "caracterelor albe " este suprimata ; pentru a citi urmatoreul caracter altul de cit
"caracterele albe" se foloseste %1s. s-un sir de caractere este asteptat ; argumentul corespunzator trebuie sa fie un pointer al unui tablou de caractere destul de mare pentru a incapea sirul si nun terminator `0 care va fi adaugat. f-un numar in virgula flotanta este asteptat
; argumentul corespunzator trebuie sa fie un pointer la un cimp "float". Un caracter de conversie e este sinonim cu f. Formatul prezentat la intrare pentru un
"float" este alcatuit dintr-un semn optional, un sir de numere care pot sa contina si un punct zecimal si un cimp de exponent care este format din E sau e urmat de un intreg cu semn.
Caracterele de conversie d, v si x pot fi precedate de litera l pentru a indica un pointer la "long" mai gdegraba decit
"int" care apare in list ta de argumente. Similar litera l inainte de E sau f indica un pointer la "double" in lista de argumente.
De exemplu: int i; float x; char namea50i; scanf("%d%f%s", Di, Dx, name); cu linia de intrare
25 54. 32E-1 Thompson va asigna valoarea 25 lui i, 5. 432 luix si plaseaza sirul
"Thompson" terminat prin `0in "name". Cele trei cimpuri
de la intrare pot fi separate de orice blancuri, tab-uri si newline-uri.
Apelarea: int i; float x; char namea50i; scanf("%2d%f%*d%2s, Di, Dx, name); cu intrarea
56789 0123 45a72 va asigna lui i, 789. 0 lui x, va sari peste 0123 si plaseaza
"45" in "name". Urmatoarea apelare la orice rutina de introducere
va incepe cautarea cu litera a. In aceste doua exemple "name" este deja un pointer si de aceea nu trebuie precedat de D.
Ca un alt exemplu, calculul rudimentar de la capitolul 4 poate fi acum rescris cu scanf pentru a face conversia de intrare.
#include<stdio.h> main() /* rudimentary desk calculator */
A double sum, v; sum=0;
while(scanf("%lf", Dv)!=EOF) printf("`t%. 2f`n", sum+=v);
S scanf se popreste cind se epuzeaza sirul de control ori cind data de intrare difera prea mult de specificatia de control. Este returnata o valoare egala cu numarul de date de intrare introduse cu succes. La sfirsitul fisierului este returnat EOF ; de observat ca acesta este diferit de 0 , ceea ce inseamna ca urmatorul caracter de la intrare nu se mai converteste prin prima specificatie din sirul de control. Urmatorul apel la scanf se rezuma sa caute imediat dupa ultimul caracter deja returnat.
Un avertisment final: argumentele lui scanf trebuie sa fie pointeri. De departe cea maiobisnuita eroare este sa scrii scanf("%d", n); in loc de scanf("%d", Dn);
7.5. Conversii de format in memorie
Functiile scanf si printf au corespondente functiile sscanf si sprintf care executa aceleasi tipuri de conversii, dar care opereazza asupra unui sir nu asupra unui fisier. Formatul general este: sprintf(string, control, arg1, arg2,...) sscanf(string, control, arg1, arg2,...) sprintf formateaza argumentele arg1, arg2, etc, conform sirului
"control" ca mai inainte, dar plaseaza rezultatele in "string"
in loc de iesirea standard. Desigur "string" trebuie sa fie suficient de mare pentru a primi rezultatul. Ca exempolu, daca
"name" este un tablou de caractere si n este un intreg, atunci: sprintf(name, "temp%d", n); creaza un sir de forma tempnnn in "name", unde nnn este valoarea lui n. sscanf face conversia inversa -imparte sirul "string" conform formatului din "control" si plaseaza valorile rezultate in arg1, arg2, etc. Aceste argumente trebuie sa fie pointeri. Astfel: sscanf(name, "temp%d", @n); n la valoarea digitilor din sir care urmeaza dupa temp in "name".
Exercitiul 7.2. Rescrieti exemplul de calculator din capitolul 4 utilizind scanf si/sau sscanf pentru a face intrarea si conversia numerelor.
7.6 Acces la fisiere
Programele scrise pina acum toatecitesc intrarea standard si scriu iesirea standard.
Urmatorul pas in I/O este de a scrie un program care acceeaza un fisier care nu este deja conectat programului. Un program care ilustreaza necesitatile pentru astfel de operatii este "cat", care conecteaza un set de fisiere specificate spre iesirea standard. "cat" este utilizat pentru tiparirea fisirelor la terminal si ca un scop general este utilizat ca un colector de intrare pentru programele care nu au capabilitatea de a accesa fisirele prin nume. De exemplu comanda: cat x. c y. c tipareste continutul fisierelor x. c si y. c la iesirea standard.
Intrebarea este cum sa aranjam ca fisierele specigficate sa fie citite adica cum sa controlam numele externe cu declaratiile care de fapt citesc datele.
Regulile sint simple. Inainte de a se citi sau scrie intr-un fisier, l trebuie deschis cu ajutorul functiei fopen din biblioteca standard. fopen ia un nume extern (ca x. c sau y. c ), face citeva manipulari si negocieri cu sistemul de operare(detalii care nu ne intereseaza) si reruneaza un nume intern care trebuie utilizat ulterior la citirile si scrierile fisireului.
Acest nume intern este de fapt un pijnter numit "file pointer", la o structura care contine informatii despre fisiere ca, adresa unui buffer pozitia curenta in bufer, daca se citeste sau se scrie in fisier, s. am. d. Utilizatorii nu trebuie sa cunoasca detaliile deoarece o parte din definirile standard I/O obtinutede la "stdio.h" este o definire de structura numita
FILE. Singura declaratie necesara pentru un pointer de fisier (file pointer) este exemplificata de
FILE*fopen(), *fp;
Aceasta spune ca fp este un pointer la FILE, si fopen returneaza un pointer la FILE. Observati ca FILE este un nume de tip, la fel cu "int" nu o eticheta de structura: este implementat ca un typedef(Detalii in capitolul 8).
Actuala apelare a lui fopen in program este: fp=fopen(name, mode);
Primul argument a lui fopen este numele (name) fisierului, care este un sir de caractere. Al doilea argument este modul
"mode", de asemenea un sir de caractere care indica cum se intentioneaza sa fie utilizat fisier ul. Modurile permise sint citire (read-"r"), scriere(write-"w") sau adaugare ("a").
Daca deschideti un fisier care nu exista: pentru scriere sau adaugare, el este creat (daca este posibil). Daca se deschide un fisier existent in scriere, acest fisier este sters.
Incercarea de a citi un fisier care nu exista constituie o eroare. Mai exista si alte manevre care cauzea erori ca incercarea de aciti un fisier pt. care nu aveti permisiunea. Daca exista vreo eroare, fopen returneaza in pointerul nul valoarea NULL
(care pt. convenienta este de asemenea definita in stdio.h).
Urmatorul pas este de aciti sau scrie fisierul odata deschis.
Aici exista mai multe posibilitati dintre care getc si putc sint cele mai simple. getc returneaza urmatorul caracter din fisier ;are nevoie de fisier pentru a-i specifica care fisier.
Astefl c=getc(fp) plaseaza urmatorul caracter din fisierul referit prin fp in c si EOF cind ajunge la sfirsitul fiserului. putc este inversul lui getc: putc(c, fp) pune caracterul c in fisierul fp si returneaza c. La fel cu getchar si puchar, getcsi putc pot fi macrouri in loc de functii.
Cind este demarat un program, trei fisiere sint deschise in mod automat si sint furnizate pointerele pentru ele. Aceste fisiere sint intrarea standard, iesirea standard, si iesirea standard pentru erori ; pointerele de fisiere corespunzatoare sint stdin, stdout si stderr. Normal toate acestea sint conectate la terminal, dar stdin si stdout pot fi redirectate asa cum s-a descris in paragraful 7.2. getchar si putchar pot fi definite cu ajutorul lui getc si putc, stdiu si stdout astfel:
#define getchar() getc(stdiu)
#define putchar(c)putc(c, stdout)
Pentru intrarea sau iesirea formatata afisierelor, functiunile fscanf s si fprintf pot fi utilizate. Acestea sint identice cu scanf si printf, de retinut ca primul argument, este un pointer de fisier care specifica fisierul de citit sau scris ; sirul de control este al doilea argument.
Cu aceste preliminarii, sintem acum in pozitia de a rescrie programul "cat" de concatenare a fisierelor. Premisa de baza este cea care a fost gasita convenabila pentru atitea programe pina acum: dacaexista linii de comanda cu argumente, sint executate in ordine. Daca nu exista argumente este preluata intrarea standard. Sub aceasta forma programul poate fi folosit de sine statator sau ca o parte a unora mai mari.
#include <stdio.h> main(argc, argv) /* cat:concatenate files */ int argc; char *argvai
A
FILE*fp, *fopen(); if(argc==1) /* no args;copy standard inp */ filecopy(stdiu); else
while(--argc>0) if((fp=fopen(*++argv, "r"))==NULL)A printf("cat:can't open%s`n", *argv); break;
SelseA filecopy(fp); fclose(fp);
S
S filecopy(fp) /*copy file fp to standard output */
FILE *fp
A int c:
while((c=getc(fp))!=EOF) putc(c, stand);
S
Pointerele de fisiere stdiu si stdout sint predefinite in biblioteca standard I/O ca iesirea si intrarea standard: ele pot fi utilizate oriunde poate fi utilizat un obiect de tipul
FILE, Ele sint constante , nu variabile asa ca nu incercati sa le asigurati.
Functia fclose este inversul lui fopen ; ea intrerupe conexiunea intre pointerul fisierului si numele extern al fisierului, care a fost stabilita de fopen, eliberind pointerul fisierului pentru un alt fisier. Deoarece cele mai multe sisteme de operare limiteaza numarul de fisiere dechise simultan de un program, este o idee buna de a le elibera in momentul cind nu maio este nevoie de ele, asa cum am facut in programul cat.
Exista de asemenea un alt motiv pentru a face fclose pe un alt fisier in iesire -curata bufferul in care putc colecteaza iesirea. fclose este apelat automat pentru fiecare fisier dechis atunci cind programul se termina normal.
7.7 Tratarea erorilor -stderr si exit
Tratamentul erorilor in cat nu este ideal. Problema este ca daca unul d din fisiere nu poate fi accesat din vreun motiv oarecare, diagnosticul erorii este tiparit numai la sfirsitul iesirii concatenate. Aceasta este aceptabil dacaiesirea se face pe un terminal, dar este rau daca iesirea este un fisier sau un alt program via o pipeline.
Pentru a trata aceasta situatie maibine, un al doilea fisier de iesire numit stderr este asignat programului, la fel castdin si stdout. Daca e este posibil, stderr apare pe terminalul utilizatorului chiar daca iesirea standard este redirectata.
Sa revizuim programl cat in asa fel ca mesajele de eroare sa apara in fisierul standard de erori
#include <stdio.h> main(argc, argv) /* cat: concatenate files *? int argc: char *argvai;
A
FILE*fp, *fopen(); if(argc==1) /* no args: ; copy standard input */ filecopy(stdiu); else
while(--argc>0) if((fp=fopen(*++argv, "r"))==NULL)A fprintf(stderr, "cat:can't open%s`n", *argv);
SelseA filecopy(fp);A fclose(fp);
S exit(0);
S
Programul semnaleaza erorile in doua feluri. Diagnosticul de iesire produs de catre fprintf merge in stderr, astfel el gaseste drumul catre terminalul utilizatorului in loc sa dispara printr-un pipeline sau fisier de iesire.
Programul de asemenea utilizeaza si functia exit din biblioteca standard care termina executia programului cind este apelata.
Argumentul lui exit este utilizabil de catre orice proces care il apeleaza, astfel succesul sau esecul programului poate fi testat de un alt program pentru care cel dinainte este un subprogram. Prin conventie returnarea valorii 0 semnaleaza ca totul ste OK, iar diferite valori nonzero semnifica situatii anormale. exit apeleaza fclose pentru fiecare fisier deschis in iesire pentru a curata bufferul, apoi cheama rutina numita -exit.
Functia exit determina terminarea imediata fara curatarea bufferului desigur exit poate fi apelata si direct.
7.8. Introducerea si extragerea unei linii
Biblioteca standard contine o rutina numita fgets care este similara functiei getline pe care am utilizat-o pina acum.
Apelarea: fgets(line, MAXLINE, fp) citeste urmatoarea linie de la intrare (incluzind newline) din fisierul fp in tabloul de caractere numit line ; cel muklt
MAXLINE-1 caractere vor fi citite. Linia rezultata este terminata prin \0. Normal fgets returneaza linia ; la sfirsitul fisierului returneaza NULL. (Getline returneaza lungimea liniei si zero pentru sfirsitul fisierului).
Pentru iesire, functia scrie un sir(care nu trebuie sa contina newline) intr-un fisier. fputs(line, fp)
Pentru a arata ca nu exista nimic magic cu functiile fgets si fputs mai jos sint copiate din biblioteca standard de intrare
/iesire.
#include <stdio.h> char *fgets(s, n, iop) /* get at most n chars from iop */ char *s int n; register FILE*iop;
A register int c; register char *cs; cs=s
while(--n>0$$(c=getc(iop))!=EOF) if((*cs++=c)=='\n') break
*cs='\0'; return((c==EOF$$cs==s)?NULL:S);
S fputs(s, iop) /* put string s on file iop */ register char *s; register FILE *iop;
A register int c;
while(c=*s++) putc(c, iop);
S
Exercitiul 7.3. Scrieti un program de comparare a doua fisiere, si tipariti prima linie si pozitia caracterelor cind difera.
Exercitiul 7.4. Modificati programul de gasire a tipului din capitolul 5 asa fel incit sa aibe intrarea dintr-un set de fisiere de intrare numite iar daca nu sint numite fisiere de intrare, de la intrarea standard. Trebuie tiparit numele fisierului cind este detectata o linie potrivita ?
Exercitiul 7.5. Scrieti un program de tiparire a unui set de fisiere, in care fiecare sa inceapa pe pagina noua cu un titlu si un contor de pagini pentru fiecare fisier.
7.9. Citeva functii amestecate
Biblioteca standard pune la dispozitie o varietate de functii, citeva fiind deosebit de utile. Am mentionat deja functiile cu siruri strlen, strepy, strcat si strcmp. Urmeaza alte citeva.
Testarea clasei caracterelor si conversia lor
Mai multe macrouri executa teste asupra caracterelor si conversia lor: isalpha(c) nonzero daca c este alfabetic si zero daca nu. isupper(c) nonzero daca c este litera mare (upper case)si 0 dacanu. islower -nonzero daca c este caracter mic (lower case)si 0 daca nu. isdigit -nonzero daca c este digit si zero daca nu. isspace -nonzero daca c ete blanc, tab sau newline si 0 daca nu. toupper -converteste c in caracter mare (upper case) tolower(c) -converteste c in caracter mic (lower case).
Ungetc
Biblioteca standard contine o versiune restrictiva a functiei ungetch pe care am scris--o in capitolul 4; se numeste ungetch. ungetch(c, fp) impinge caracterul c inapoi in fisierul fp. Numai un caracter din fisierc poate fi tratat astfel ungetc poate fi utilizat cu oricare din functii le si macrouruile de introducere ca scanf, getc sau getchar.
Apel system
Apelarea functiei system(s) executa comanda continuta in sirul de caractere s apoi reia programul curent. Continutul lui s depinde mult de sistemul de operare. Ca un exemplu ordinar in UNIX linia system("date"); determina rularea parogramului date care tiparesete data si momentul zilei.
Managementul memoriei
Functia calloc este asemanatoare cu alloc pe care am utilizat-o in capitolele precedente. calloc(n, sizeof(object)) returneaza un pointer daca este suficient spatiu pentru cele n obiecte de dimensiunea specificata sizeof sau NULL daca cererea poate fi satis facuta. Memoria este initializata cu zero.
Pointerul are aliniamentul adecvat obiectelor respective, dar el trebuie introdus intr-un tip corespunzator. cfree(p) elibereaza spatiul pointat prin p unde p este initial obtinut prin apelarea lui calloc. Nu exista restrictii asupra ordinii in care spatiul este eliberat, dar este o mare greseala sa eliberezi ceva ce nu ai obtinut prin apelarea functiei calloc.