This is an old revision of the document!
In cadrul acestui laborator, vom studia clasa string si fluxurile de intrare/iesire (stream).
Ca referinte externe, recomandam urmatoarele capitole din Absolute C++:
Biblioteca Standard C++ (Standard C++ Library) cuprinde toate bibliotecile standard C precum si biblioteci dedicate C++.
Pentru a accesa tot ce ne este pus la dispozitie de catre libraria string, vom apela urmatoarea comanda:
#include <string>
Crearea si initializarea de obiecte de tip string se face folosind constructorii pusi la dispozitie de aceasta clasa.
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) |
#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; }
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); |
#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; }
#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; }
#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; }
#include <iostream> #include <string> #include <iomanip> using namespace std; int main() { // operatorii >> si << string s; cin >> s; cout << s << '\n'; return 0; }
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 |
#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; }
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).
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.
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:
bool 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
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 :
-dec(specifica baza10) -oct(specifica baza8) -hex(specifica baza16) -endl(end of line, adica insereaza'\n') -ws(ignora spatiile goale: space, tab ) -ends(end of string, adica insereaza '\0') -flush(goleste bufferul de iesire)
exemplu: intx; 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)
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
Nota: 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 : write si 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);