printf

De la Wikipedia, enciclopedia liberă.
Salt la navigare Salt la căutare

printf este o funcție implementată în limbaje de programare pentru a afișa un șir construit conform unui format specificat la ieșirea standard . Această funcție provine din limbajul C , unde are un prototip similar cu următorul:

 int printf ( format const char * , ...)

Parametrul de format este un șir care descrie formatul de urmat în ieșire și care folosește secvențe de substituent , introdus de simbolul procentual („%”), pentru a specifica poziția relativă și tipul de date cu care se compune șirul.

De exemplu, în limbajul C.

 printf ( "Color% s, number1% d, number2% 05d, hex% x, float% 5.2f. \ n " ,
             „roșu” , 123456 , 89 , 255 , 3,14 );

va imprima următoarea linie (cu excepția caracterului newline, \ n ):

 Culoare roșie, număr1 123456, număr2 00089, hex ff, float 3.14.

Funcția printf returnează numărul de caractere tipărite sau un număr negativ dacă a apărut o eroare de ieșire.

Perl are și funcția printf , dar folosește caractere diferite pentru conversie. Python are funcționalități similare (operatorul % ). Biblioteca GLib conține funcția g_print , o implementare a printf .

Sistemele POSIX au un program numit printf [1] , care poate fi utilizat de exemplu în script-uri shell ; poate fi utilizat în locul comenzii echo în situații în care acesta din urmă nu este portabil . De exemplu:

 echo -n -e "$ FOO \ t $ BAR '

poate fi rescris portabil ca:

 printf '% s \ t% s' "$ FOO" "$ BAR"

Limbajul PHP are și funcția printf , care este aceeași cu cea a C / C ++.
Nu există printf programul MATLAB , dar există două dintre extensiile sale: sprintf și fprintf , care acceptă aceeași sintaxă în șirul de format.

Limbajul JavaScript , deși este un limbaj de programare între paranteze, nu are o funcție printf .

Funcții derivate

Standardul C specifică unele funcții derivate din printf care permit extinderea utilizărilor sale:

fprintf

 int fprintf ( FILE * stream , const char * format , ...)

fprintf permite scrierea ieșirii în fișier . Această funcție este adesea utilizată pentru a scrie la erori standard sau fișiere text . Poate fi de fapt folosit pentru a scrie pe orice fișier sau flux deschis cu funcția fopen , deși utilizarea fprintf pentru a scrie date binare poate fi problematică sau cel puțin incomodă.

sprintf

 int sprintf (format char * str , format const char * , ...)

sprintf tipărește pe un șir (matrice de caractere) în loc de ieșire standard. Utilizatorii trebuie să se asigure, prin protecție de calcul sau de spargere a stivei, că șirul rezultat nu este mai mare decât memoria alocată pentru str . Nu vă asigurați că acest lucru poate provoca o revărsare a bufferului .

Rețineți că în PHP funcția sprintf nu are argumentul str ; dimpotrivă, funcția returnează șirul de ieșire formatat.

Prototipul funcției în PHP este:

 string sprintf ( format șir const , ... )

O alternativă sigură la sprintf

Ca alternativă, multe medii oferă funcția snprintf :

 int snprintf ( char * str , size_t size , const char * format , ...)

snprintf garantează să nu scrieți mai mult de octeți de mărime în str , pentru a evita riscul de depășire a bufferului , ca în următorul cod:

 #define BUFFER_SIZE 50
char buf [ BUFFER_SIZE ];
int n ;

...

n = snprintf ( buf , BUFFER_SIZE , "Numele tău este% s. \ n " , nume de utilizator );
if ( n < 0 || n > = BUFFER_SIZE )
   / * Eroare de manipulare * /

Dacă numele de utilizator din exemplul anterior depășește 50 de caractere, funcția va limita șirul salvat în buf prin trunchierea caracterelor finale. Acest lucru poate părea nedorit, dar preferabil în fața unei vulnerabilități de securitate, la care poate duce adesea un deversament de tampon . De asemenea, codul de retur al funcției snprintf indică câte caractere ar scrie funcția pe șir cu suficient spațiu. Sistemele pot utiliza aceste informații pentru a aloca un tampon nou (mai mare) dacă au nevoie de tot șirul netăiat.

snprintf nu face parte din standardul ANSI C implementat pe scară largă, cum ar fi sprintf . Cu toate acestea, a devenit parte a limbajului cu standardul C99 și a fost adesea prezent în bibliotecile C chiar înainte de acest standard.

O altă alternativă sigură la sprintf este asprintf :

 int asprintf ( char ** ret , const char * format , ...)

asprintf alocă automat suficientă memorie pentru a ține șirul final. Funcția inițializează *ret cu un pointer la șirul rezultat sau cu o valoare nedefinită dacă apare o eroare (Rețineți că Glibc este singura implementare care nu inițializează întotdeauna *ret la NULL în cazul în care apare o eroare). Programatorul, utilizând asprintf , este responsabil pentru eliberarea memoriei alocate după utilizare. Deși nu face parte din niciun standard, asprintf este inclus în bibliotecile C ale multor sisteme de operare (inclusiv OpenBSD , FreeBSD și NetBSD ).

vprintf, vfprintf, vsprintf, vsnprintf și vasprintf

 int vprintf ( format const char * , va_list ap );
int vfprintf ( FILE * stream , const char * format , va_list ap );
int vsprintf (format char * str , format const char * , va_list ap );
int vsnprintf ( char * str , size_t size , const char * format , va_list ap );
int vasprintf ( char ** ret , const char * format , va_list ap );

Aceste funcții sunt similare celor precedente fără v , cu excepția faptului că utilizează liste de argumente variabile. Aceste funcții oferă programatorilor posibilitatea de a-și crea propriile variante de printf . De exemplu, un programator ar putea scrie o funcție

 void fatal_error ( const char * format , ...)

Care ar folosi macro-ul va_start pentru a obține o variabilă va_list din parametrii suplimentari, imprimă un mesaj pe dispozitivul de eroare standard folosind vfprintf , după care variabila va_list curăță cu macro-ul va_end și, în cele din urmă, efectuează sarcinile necesare pentru a închide programul prin eliberând memoria.

O altă aplicație obișnuită a acestor funcții este de a scrie un printf arbitrar care imprimă pe un alt obiect decât un fișier. O bibliotecă grafică poate oferi funcții de tip printf cu coordonate x și y:

 int graphical_printf (format int x , int y , const char * format , ...)

Acest lucru ar salva temporar șirul într-un buffer privat folosind vsnprintf sau vasprintf .

Substituenți ai formatului printf

Formatarea se face prin substituenți în șirul de format. De exemplu, dacă un program dorește să tipărească vârsta unei persoane, poate prezenta rezultatul cu prefixul „vârsta ta este”. Pentru a specifica faptul că dorim fie tipărit numărul întreg de vârstă după mesaj, putem folosi formularul:

 „vârsta ta este de% d.”

sintaxa formatului substituent este „ % [flag] [width] [. precision] [length] type ”.

tipul poate fi:

  • „d”, „i”: Imprimați un număr întreg ca o zecimală semnată. „% d” și „% i” sunt sinonime pentru ieșire, dar diferite atunci când sunt utilizate cu scanf() pentru intrare;
  • „u”: tipăriți un număr întreg ca zecimală nesemnată;
  • 'f', 'F': Imprimați o valoare reală ca număr de virgulă;
  • „e”, „E”: tipărește o valoare reală în forma exponențială standard ([-] d.ddd și [+/-] ddd); „e” folosește litere mici „e”, „E” folosește litere mari;
  • „g”, „G”: tipărește o valoare reală cu notație reală sau exponențială, alegând cea care se potrivește cel mai bine dimensiunii sale. „g” folosește litere mici, „G” folosește litere mari. Această notație diferă de notația virgulă, deoarece nu sunt incluse zerouri inutile din dreapta punctului zecimal. Punctul zecimal nu este inclus în numerele întregi;
  • „x”, „X”: tipărește un număr întreg nesemnat ca număr hexazecimal . „x” folosește litere mici, iar „X” folosește majuscule;
  • 'o': Imprimați un număr întreg nesemnat în baza octală;
  • 's': Imprimați un șir ;
  • 'c': tipărește un caracter;
  • „p”: tipăriți un pointer la gol, într-un format definit de implementare;
  • 'n': Scrieți numărul de caractere scrise până acum corect într-un parametru de pointer întreg;
  • „%”: Tipărește un caracter „%” (nu acceptă steaguri, precizie, lungime sau lățime).

Steagurile pot fi omise:

  • „+”: Printf indică întotdeauna semnul „+” sau „-” al unui număr (implicit este omiterea semnului pentru numerele pozitive). Numai pentru variabilele numerice.
  • '-': Printf stânga aliniază ieșirea acestui substituent (implicit este dreapta).
  • '#': Formă alternativă: cu 'g' și 'G', zerourile finale nu sunt eliminate; cu 'f', 'F', 'e', ​​'E', 'g', 'G', ieșirea conține întotdeauna un punct zecimal; cu 'o', 'x' și 'X', un 0, 0x sau 0X sunt prefixate la numere diferite de zero, respectiv.
  • '': Face printf insert spații în stânga ieșirii până când atinge lățimea necesară. Când este combinat cu „0” (vezi mai jos), va face semnul un spațiu pentru numere pozitive, dar celelalte caractere vor fi umplute cu zerouri.
  • „0”: face ca printf să folosească caractere „0” (în loc de spații) în stânga până când atinge o anumită lățime. De exemplu, presupunând i = 3, printf ("% 2d", i) are ca rezultat "3", în timp ce printf ("% 02d", i) are ca rezultat "03"

Lățimea poate fi omisă sau poate fi:

  • un număr : printf afișează ieșirea acestui substituent cu spații, atâta timp cât are cel puțin un număr de caractere.
  • '*': printf extinde ieșirea la n caractere, unde n este un număr întreg stocat în următorul argument. De exemplu printf („% * d”, 5, 10) va rezulta „10” tipărit cu o lățime de 5.

Precizia poate fi omisă sau poate fi:

  • un număr : Pentru tipurile numerice care nu sunt întregi (adică virgulă mobilă), porțiunea zecimală a ieșirii este exprimată cu exact numărul de cifre. Cu șiruri, tăiați ieșirea la numărul de caractere.
  • '*': La fel ca mai sus, dar utilizați o valoare întreagă în următorul argument pentru a determina numărul de zecimale sau lungimea maximă a șirului. De exemplu, printf („%. * S”, 3, „abcdef”) va duce la tipărirea „abc”.

Lungimea poate fi omisă sau poate fi:

  • 'hh': pentru tipurile întregi, printf așteaptă un argument atâta timp cât un caracter;
  • 'h': pentru tipurile de numere întregi, printf așteaptă un argument atâta timp cât un număr întreg scurt;
  • 'l': (elle) pentru tipurile întregi, printf așteaptă un argument atâta timp cât un întreg lung;
  • 'll': (elle elle) pentru tipurile de numere întregi, printf așteaptă un argument atâta timp cât un întreg lung-lung;
  • „L”: pentru tipurile cu virgulă mobilă, printf așteaptă un argument atâta timp cât un dublu lung;
  • 'z': pentru tipurile întregi, printf așteaptă un argument atâta timp cât un număr întreg de tip size_t;
  • 'j': pentru tipurile întregi, printf așteaptă un argument atâta timp cât un întreg de tip intmax_t;
  • 't': Pentru tipurile de numere întregi, printf așteaptă un argument atâta timp cât un număr întreg de tip ptrdiff_t.

Dacă sintaxa unei specificații de conversie este nevalidă, comportamentul este nedefinit. Dacă există prea puține argumente ale funcției de date pentru a furniza valori pentru toate specificațiile de conversie din șirul de model sau dacă argumentele nu sunt de tipul corect, rezultatele sunt nedefinite. Argumentele în exces sunt ignorate. În unele cazuri, comportamentul nedefinit a condus la atacuri de securitate bazate pe formatul șirului. Rețineți că unele compilatoare, cum ar fi GCC , vor verifica șirurile de format printf la compilare pentru funcții și vor raporta orice probleme.

Majoritatea limbajelor non-C au o funcție precum printf care funcționează utilizând codul de formatare „% s” și convertind obiecte în text. C ++ oferă o nouă modalitate de a rula printf. De fapt, C ++ include funcția printf într-un mecanism complet diferit, care este în general preferat.

Limbaje de programare cu printf

Notă

  1. ^ (EN) printf în Specificațiile de bază ale grupului deschis Numărul 7 IEEE Std 1003.1-2008. Adus la 30 martie 2010 .

Elemente conexe

linkuri externe

Informatică Portal IT : accesați intrările Wikipedia care se ocupă cu IT