Laboratorul 10: Biblioteca Standard C++

In cadrul acestui laborator, vom studia clasa string si fluxurile de intrare/iesire (stream).

Ca referinte externe, recomandam urmatoarele capitole din Absolute C++:

  • Capitolul 9 (Chapter 9.3: The Standard Class String, pag 393-413)
  • Capitolul 19 (Chapter 19: Standard Template Library, pag 857-915)

1. Introducere

Biblioteca Standard C++ (Standard C++ Library) cuprinde toate bibliotecile standard C precum si biblioteci dedicate C++.

Exemple

  • clasa string (operatii de procesare text)
  • clase pentru procesarea fisierelor de intrare/iesire si operatii consola: iostream, fstream etc
  • STL(Standard Template Library) = clase template (containere, iteratori, algoritmi)

2. Clasa String

Pentru a accesa tot ce ne este pus la dispozitie de catre libraria string, vom apela urmatoarea comanda:

#include <string> 

Un obiect de tip string reprezinta un sir de caractere (+informatii despre localizarea lui in memorie si dimensiunea sa).

2.1. Constructori

Crearea si initializarea de obiecte de tip string se face folosind constructorii pusi la dispozitie de aceasta clasa.

Exemple
string() creaza un obiect string default (lungimea este 0)
string(const char *s) creaza si initializeaza un string folosind un sir de caractere s
string(size_type n, char c) creaza un string cu dimensiune n si fiecare element este initializat cu c
string(const string& s) constructor de copiere
string(string s, int poz_init, int dim) creaza un string din s, incepand cu elementul de pe pozitia poz_init, de lungime dim (sau pana la finalul lui s)
String
#include <iostream>
#include <string>
using namespace std;
 
int main() {
    string s1;
    cout << "s1: " << s1 << endl;//OUTPUT: s1:
 
    string s2("al doilea string");
    cout << "s2: " << s2 << endl;//OUTPUT: s2: al doilea string
 
    string s3(s2);
    cout << "s3, copia celui de-al doilea string: " << s3 << endl;
    //OUTPUT: s3, copia celui de-al doilea string: al doilea string
 
    string s4(5, 'o');
    cout << "s4: " << s4;//OUTPUT: s4: ooooo
 
    string  s5 = "al 5-lea";//Observam ca operator= este supradefinit pentru tipul de date string
    cout << "s5: " << s5 << endl;//OUTPUT: s5: al 5-lea
 
    string s6(s5, 3, 5);
    cout << "s6: " << s6;//OUTPUT: 5-lea
 
    string s7(s5, 3, 10);//se opreste la ultimul caracter din s5
    cout << "s7: " << s7;//OUTPUT: 5-lea
 
    return 0;
}

2.2. Operatori supradefiniti

Pentru clasa string, urmatorii operatori sunt supradefiniti:

operatorul + string operator+ (const string& lhs, const string& rhs);
operatorul += string& operator+= (const string& str);
operatorul = string& operator= (const string& str);
operatorii relationali (==, !=, <, >, ⇐, >= ) bool operator== (const string& lhs, const string& rhs);
operatorul » istream& operator» (istream& is, string& str);
operatorul « ostream& operator« (ostream& os, const string& str);

Exista mai multe definitii pentru unii dintre operatorii de mai sus.

Exemple
Operatorul+
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
 
int main() {
    //operatorul+
    string s1("text");
    string s2("concatenat");
    cout << s1 + " " + s2 << '\n'; // OUTPUT: textconcatenat
    return 0;
}
Operatorul=
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
 
int main() {
    // operatorul =
    s1 = "un string";
    cout << s1 << '\n'; // OUTPUT: un string
    s2 = "alt string";
    s1 = s2;
    cout << s1 << '\n'; // OUTPUT: alt string
    return 0;
}
OperatoriiRelationari
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
 
int main() {
// operatorii relationali : ==, !=, <, >, <=, >=
    s1 = "avion";
    s2 = "bivol";
    if(s1 == s2) cout << "cele doua cuvinte sunt egale\n";
    if(s1 < s2) cout << "s1 este lexicografic mai mic decat s2\n";
    if(s1 > s2) cout << "s2 este lexicografic mai mic decat s1\n";
    if(s1 != s2) cout << "cele doua cuvinte difera\n";
    if(s1 <= s2) cout << "s1 este lexicografic mai mic sau egal cu s2\n";
    // OUTPUT: s1 este lexicografic mai mic decat s2
    //		   cele doua cuvinte difera
    //		   s1 este lexicografic mai mic sau egal cu s2
    return 0;
}
OperatoriCitireAfisare
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
 
int main() {
  // operatorii >> si <<
    string s;
    cin >> s;
    cout << s << '\n';
    return 0;
}

2.3. Metode utile

Dintre metodele clasei string, mentionam:

length → s.length() (returneaza lungimea string-ului)
empty → s.empty() returneaza daca sirul este gol sau nu
substr → s.substr(a,b) returneaza un subsir de b caractere, incepand cu pozitia a; Daca b nu este precizat, se adauga la subsir toate caracterele incepand cu pozitia a
replace → s.replace(a,b,s2) (inlocuieste portiunea de sir care incepe pe pozitia a si tine b caractere cu continutul sirului 2)
find → s.find(secv) returneaza prima pozitie unde este gasita secventa secv, sau string::npos(constanta a clasei string), in cazul in care secventa nu a fost gasita)

Alte metode de cautare in string-uri:

find_first_of returneaza prima pozitie din string unde se gaseste oricare dintre caracterele din secventa trimisa ca parametru
find_last_of returneaza ultima pozitie din string unde se gaseste oricare dintre caracterele din secventa trimisa ca parametru
rfind cauta de la final spre inceputul stringului si returneaza prima pozitie pe care se gaseste caracterul/secventa sau string::npos

Exista mai multe versiuni supradefinite pentru metodele mentionate.

Exemplu
Exemplu_Metode
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
 
int main() {
    // length
    string s("bine");
    cout << s.length() << '\n'; // OUTPUT: 4
 
    // empty
    if(s.empty()) cout << "s este gol\n";
    if(!s.empty()) cout << "s nu este gol\n"; // OUTPUT: s nu este gol
 
    // substr
    string s1("calculator");
    string s2 = s1.substr(0, 8);
    cout << s2 << '\n'; // OUTPUT: calculat
 
    string s3 = s1.substr(3);
    cout << s3 << '\n'; // OUTPUT: culator
 
    // replace
    s1 = "doar";
    s2 = s1.replace(1, 2, "inozau");
    cout << s1 << '\n'; // OUTPUT: dinozaur
 
    // find
    int pos;
    pos = s1.find("ino");
    cout << pos << '\n'; // OUTPUT: 1
 
    if(s1.find('z') == string::npos) cout << "secventa nu a fost gasita";
    //OUTPUT : secventa nu a fost gasita
 
    return 0;
}

Pentru a transforma o litera dintr-un string in litera mica/mare, putem folosi tolower() si toupper(), care nu sunt metode ale clasei string, ci functii din biblioteca standard C.

3. Stream

In C++ exista o ierarhie de clase predefinite, care asigura un suport eficient pentru operatiile de intrare/iesire, atat cu consola cat si cu discul. Conceptul de baza este de dispozitiv logic de intrare/iesire (flux de intrare/iesire).

Aceste fluxuri sunt numite stream-uri.

Fisierele care asigura interfata cu clasele predefinite sunt:

  1. <iostream> (operatii consola)
  2. <fstream> (operatii fisiere)

3.1. iostream

Denumirea de iostream provine de la standard input-output stream. In C++, cele doua metode fundamentale pentru a citi si, respectiv, a scrie, sunt cin si cout.

cin:

Este o instanta a clasei istream si se foloseste pentru a citi input-ul de la o sursa (sursa standard este tastatura). Este urmat de operatorul de extractie (»), care extrage inputul din obiectul cin, introdus de la tastatura.

cout:

Este o instanta a clasei ostream si se foloseste pentru a introduce date in dispozitivul de output (de obicei ecranul). Utilizand operatorul de insertie («) datele sunt introduse in stream-ul de output (cout) pentru a aparea pe ecran.

Operatorii « si >> sunt definiti dupa cum urmeaza:

ostream &operator<< (ostream &, consttip_de_baza &);

istream &operator>> (istream &, tip_de_baza &);

Acestia pot fi supradefiniti pentru tipuri de date definite de utilizator:

friend ostream& operator<< (ostream&, constTIP &);
friend istream& operator>> (istream&, TIP &);

Pe langa operatorii « si », clasele istream si ostream au implementate functiile elementare get si put

ostream& put (char c);
istream& get (char& c);
Exemplu
char ch;
cin.get(ch);
cout.put(ch);
Functii de citire/modificare a starii:
obool bad(); arata daca a existat o eroare la efectuarea ultimei operatii
bool good(); arata daca ultima operatie s-a efectuat cu succes
void clear(); sterge indicatorii de eroare
Manipulatori

Manipulatorii reprezinta operatii ce pot fi inserate in secventele de citire/scriere. Acestia fac ca urmatoarele operatii de citire sau scriere sa aiba loc cu un alt tip de conversie.

Sintaxa:
cout << manipulator << ....;

Exemplu:

cout << hex << 10 << endl << 11;//OUTPUT: a b
cin >> oct >> i; // i va fi citit de la consola in baza 8

Manipulatorii fara parametri sunt:

  1. dec (specifica baza10)
  2. oct (specifica baza8)
  3. hex (specifica baza16)
  4. endl (end of line, adica insereaza'\n')
  5. ws (ignora spatiile goale: space, tab )
  6. ends (end of string, adica insereaza '\0')
  7. flush (goleste bufferul de iesire)

Exemplu:

int x;
cin >> hex >> x; //F
cout << dec << x;//15
string s, s1;
cin >> ws >> s; // introducde la tastatura textul: ”xx yy zz”
cout << s; //xx
cin >> s1; //fara sa scriu ceva de la tastatura, in s1 se citeste in continuare yy
cout << s1; //yy
cout << flush;

Manipulatori cu parametri (definiti in iomanip.h):

setprecision (int n) - (pentru numerele reale) precizia este setata la n zecimale
setw (int n) - seteaza latimea campului pentru afisare la n
setfill (char ch) - selecteaza caracterul de umplere (completeaza pozitiile libere din camp)

3.2. ifstream, ofstream si fstream

Pentru deschiderea de fisiere putem folosi constructorii cu/fara parametri pusi la dispozitie pentru toate tipurile de fisiere (intrare, iesire si intrare-iesire)

ofstream::ofstream(const char*nume, int mod=ios::out, int acces=0)
nume - numele fisierului
mod - modul de acces
acces - tipul de protectie/acces

Exemplu:

ofstream ofis("date1.txt",ios::app);

Modurile (preferinite in clasa ios) sunt:

  • ios::in - intrare
  • ios::out - iesire
  • ios::ate - deschidere cu pozitionare la sfarsitul fisierului
  • ios::app - append, adaugare la sfarsitul fisierului
  • ios::binary - deschidere in mod binar

Modurile pot fi combinate cu SAU logic la nivel de bit (|)

Acces

  • 0 - normal
  • 1 - read-only
  • 2 - hidden
  • 3 - sistem

Se poate folosi si functia cu efect similar:

void open (const char *nume_fisier, int mod, int acces)

In urma deschiderii, este indicata testarea pentru erori:

if (!numefis) cout << "eroare";

Pentru inchiderea unui fisier, se foloseste functia “void close();”, functie ce este apelata de destructorul claselor ce lucreaza cu fisiere, deci fisierul va fi inchis automat la finalul duratei de viata a variabilei de tip fisier.

Putem citi o linie dintr-un fisier text (sau cin) cu functia:

getline(unsigned char *buf,   int l,    char delim);

Functia getline citeste in buf cel mult l-1 caractere, pana la intalnirea caracterului delim, care este implicit '\n'(newline) si pune '\0' la sfarsitul liniei citite.

Exemplu:

ifstream ifis("date2.dat");
char buf[256];
while(!ifis.eof()) {
      ifis.getline(buf, 256, '\n');
      cout << buf << endl;   
}

A se consulta cursul pentru mai multe exemple!

Fisiere binare

In cazul fisierelor binare, nu se pot folosi functiile obisnuite de citire/scriere deoarece datele nu sunt formatate in vreun fel anume.

Clasele specializate pentru fisiere binare includ doua functii pentru citirea si scrierea secventiala:

  1. write
  2. read
istream& read(unsigned char *buf, intn);
ostream& write(constunsigned char *buf, intn);

Functiile citesc/scriu din/in fisierul respectiv n octeti in/din buf

Pozitionarea absoluta in fisierul binar este realizata de metodele seekg (citire din ifstream) si seekp (scriere in ofstream):

ifstream& seekg(long poz, int reper);
ofstream& seekp(long poz, int reper);
poz = pozitia in octeti
Reper poate fi una dintre constantele: 
   ios::beg (pozitionare fata de inceput)
   ios::cur (fata de pozitia curenta) 
   ios::end (fata de sfarsit)
poo-is-aa/laboratoare/10.txt · Last modified: 2024/08/14 20:10 (external edit)
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0