#include <iostream>
#include <iomanip>
#include <cstring>
#include <cstdlib>
using namespace std;
class Stringhetta
{
//funzione friend che servono per gli operatori << e >>
friend ostream &operator<<(ostream &uscita, const Stringhetta &s);
friend istream &operator>>(istream &ingresso, Stringhetta &s);
public:
Stringhetta(const char *s = "");// costruttore di defoult, assegna per defoult una Stringhetta vuota
Stringhetta(const Stringhetta &s);// costruttore di copia
~Stringhetta();//distruttore
// riassegnazione di operatori
const Stringhetta &operator=(const Stringhetta &s);//operatore di assegnamento
const Stringhetta &operator+=(const Stringhetta &s);//operatore di concatenamento
const Stringhetta &operator+=(const char s);//operatore di concatenamento
const Stringhetta &operator+(const Stringhetta &s);//operatore di concatenamento in Stringhetta nuova
bool operator!() const;// risponde alla domanda !s -> "la Stringhetta this è vuota?" Questa è una ridefinizione non in linea con il significato dell'operatore !
bool operator==(const Stringhetta &s) const;// verifica se this == s
bool operator<(const Stringhetta &s) const;// verifica se this < s
char &operator[](int n);//operatore di indicizzazione lvalue per modifica
char operator[](int n) const;//operatore di indicizzazione rvalue
Stringhetta operator()(int n, int l = 0);//estrae una sottostringa dalla posizione n, lunga l, l per default può valere 0 lo considererò "finoi alla fine"
int getLunghezza() const;//restituisce la lunghezza della Stringhetta
// riassegnazione di operatori in line
bool operator!=(const Stringhetta &s) const {
return !(*this == s);//!(==)
}// verifica se this != s e permette la chiamata in line della funzione serve la classe proxi
bool operator>(const Stringhetta &s) const {// verifica se this > s
return (s < *this); // this > s -> s < this
}// verifica se this > s e permette la chiamata in line della funzione serve la classe proxi
bool operator<=(const Stringhetta &s) const {// verifica se this <= s
return !(s < *this); // this <= s -> s >= this -> !(s < this)
}// verifica se this <= s e permette la chiamata in line della funzione serve la classe proxi
bool operator>=(const Stringhetta &s) const {// verifica se this >= s
return !(*this < s); //this >= s -> !(this < s)
}// verifica se this >= s e permette la chiamata in line della funzione serve la classe proxi
//funzione simile a Stringhetta operator()(int n, int l = 0); ma che nonn usa strcpy
Stringhetta SottoStringhettina(int da,int quanto)
{
int k=0;
if(quanto>lunghezza)
quanto =lunghezza+1;
else if(quanto <=0)
quanto =0;
else
{
}
char *ptrTmpStringa = new char[quanto-da + 1];
Stringhetta temp(ptrTmpStringa);
for(int i=da;i<da+quanto;i++)
{
temp.ptrStringa[k++]=ptrStringa[i];
}
temp.ptrStringa [k]='\0';
return temp;
}
private:
//membri dato
int lunghezza;//lunghezza della Stringhetta senza il carattere terminatore
char *ptrStringa;//puntatore al primo carattere della Stringhetta
//funzioni varie
void setStringa(const char *s);//funzione che imposta la Stringhetta
};
Stringhetta::Stringhetta(const char *s)
:lunghezza(s != "" ? strlen(s) : 0)// lunghezza o 0 oppure lunghezza di s
{
//cout << "costruttore di default e di conversione: " << s << endl;
setStringa(s);// utilizzata per creare l'istanza dell'oggetto
}
Stringhetta::Stringhetta(const Stringhetta & s)//costruttore di copia
: lunghezza(s.lunghezza)
{
//cout << "costruttore di copia: " << s.ptrStringa << endl;
setStringa(s.ptrStringa);// utilizzata ancora per creare l'istanza dell'oggetto
}// la corretta costruzione dell'oggetto è sempre gestita dalla funzione setStringa(s)
Stringhetta::~Stringhetta()
{
//cout << "distruttore: " << ptrStringa << endl;
delete [] ptrStringa;
}
const Stringhetta & Stringhetta::operator=(const Stringhetta & s)
{
// evitiamo l'autoassegnamento
if (&s != this) {
delete[] ptrStringa;//cancello la vecchia Stringhetta
lunghezza = s.lunghezza;
setStringa(s.ptrStringa);// utilizzata ancora per creare l'istanza dell'oggetto
}
else {
// se cerco di copiare su me stesso, avviso
}// in entrambi i casi ritorno this
return *this;
}
const Stringhetta & Stringhetta::operator+=(const Stringhetta & s)
{
int newLunghezza = this->lunghezza + s.lunghezza;
char *ptrTmp = new char[newLunghezza + 1];//mi creo il nuovo contenuto dell'oggetto
strcpy(ptrTmp, ptrStringa);//copio nella nuova Stringhetta la prima parte, quella dell'oggetto "chiamante"
strcpy(ptrTmp + lunghezza, s.ptrStringa);//(ptrTmp + lunghezza) è il puntatore alla posizione dove inserire la Stringhetta successiva da concatenare
delete [] ptrStringa;// cancello lo spazio di memoria occupato precedentemente
ptrStringa = ptrTmp; // associo il nuovo puntatore al puntatore dell'oggetto
lunghezza = newLunghezza;// il valore della nuova lunghezza
return *this;
}
//serve per formare una stringa aggiungendo caratteri
const Stringhetta & Stringhetta::operator+=(const char s)
{
int newLunghezza = this->lunghezza + 1;
char *ptrTmp = new char[newLunghezza + 1];//mi creo il nuovo contenuto dell'oggetto
strcpy(ptrTmp, ptrStringa);//copio nella nuova Stringhetta la prima parte, quella dell'oggetto "chiamante"
ptrTmp[lunghezza]=s;
ptrTmp[lunghezza+1]='\0';
delete [] ptrStringa;// cancello lo spazio di memoria occupato precedentemente
ptrStringa = ptrTmp; // associo il nuovo puntatore al puntatore dell'oggetto
lunghezza = newLunghezza;// il valore della nuova lunghezza
return *this;
}
const Stringhetta & Stringhetta::operator+(const Stringhetta & s)
{
Stringhetta *ptrTmpStringa = new Stringhetta("");//allochiamno la memoria per la Stringhetta temporanea
ptrTmpStringa->lunghezza = this->lunghezza + s.lunghezza; //assegno la lunghezza della nuova Stringhetta
strcpy(ptrTmpStringa->ptrStringa, this->ptrStringa);//copio nella nuova Stringhetta la prima parte, quella dell'oggetto "chiamante"
strcpy(ptrTmpStringa->ptrStringa + lunghezza, s.ptrStringa);//(ptrTmp + lunghezza) è il puntatore alla posizione dove inserire la Stringhetta successiva da concatenare
return *ptrTmpStringa;
}
bool Stringhetta::operator!() const
{
return (lunghezza == 0);// le lunghezza è uguale a 0
}
bool Stringhetta::operator==(const Stringhetta & s) const
{
return (strcmp(ptrStringa, s.ptrStringa) == 0);//strcmp ritorna 0 se le due stringhe sono uguali
}
bool Stringhetta::operator<(const Stringhetta & s) const
{
return (strcmp(ptrStringa, s.ptrStringa) < 0);//strcmp ritorna un numero negativo se la prima Stringhetta è minore della seconda
}
//serve per quando andiamo a modificare un carattere della stringa
char & Stringhetta::operator[](int n)
{
if ((n < 0) || (n >= lunghezza)) {//controllo che l'indice richiesto appartenga al range ammesso
//cerr << "Errore: indice = " << n << " out of range (" << lunghezza << ")" << endl;
return ptrStringa[lunghezza];
//exit(1);//fine del programma per errore lo maschero
}
return ptrStringa[n];//se tutto OK ritorno il carattere richiesto modificabile
}
//serve per quando andiamo a vedere un carattere della stringa
char Stringhetta::operator[](int n) const
{
if ((n < 0) || (n >= lunghezza)) {//controllo che l'indice richiesto appartenga al range ammesso
//cerr << "Errore: indice = " << n << " out of range (" << lunghezza << ")" << endl;
return '\0';
//exit(1);//fine del programma per errore
}
return ptrStringa[n];//se tutto OK ritorno il carattere richiesto costante
}
int Stringhetta::getLunghezza() const
{
return lunghezza;
}
void Stringhetta::setStringa(const char * s)
{
// funzione alla base dell'inizializzazione della classe
ptrStringa = new char[lunghezza + 1];//allochiamno la memoria necessaria (lunghezza + 1) per il carattere di terminazione
if (s != 0) {
//se s punta ad una Stringhetta la copio
strcpy(ptrStringa, s);//lunghezza + 1 è richiesto da strcpy_s per evitare errori di overflow buffer
}
else {
//altrimenti copio una Stringhetta vuota
ptrStringa[0] = '\0';
}
}
ostream & operator<<(ostream & uscita, const Stringhetta & s)
{
uscita << s.ptrStringa;
return uscita;
}
istream & operator>>(istream & ingresso, Stringhetta & s)
{
char temp[100]; //mi creo un buffer per memorizzare l'ingresso -> 99 caratteri c'è anche il terminatore
ingresso >> setw(100) >> temp;//memorizzo l'input nel buffer temporaneo
s = temp; // utilizzo la ridefinizione dell'operatore = "const Stringhetta & Stringhetta::operator=(const Stringhetta & s)"
return ingresso;
}
Stringhetta Stringhetta::operator()(int n, int l)
{
//estrae una sottostringa dalla posizione n, lunga l
if ((n < 0) || (n >= lunghezza) || (l < 0)) {//controllo la correttezza dell'indice n e controllo che l sia maggiore di 0
return "";// viene restituita una Stringhetta vuota, viene automaticamente convertita nell'oggetto Stringhetta
}
int newLunghezza;//si determina la lunghezza della sottostringa
if ((l == 0) || (n + l > lunghezza)) {//se l è uguale a 0 oppure se n+l è maggiore della lunghezza totale della Stringhetta
newLunghezza = lunghezza - n;//allora la lunghezza della nuova Stringhetta è dal'indice n fino alla fine
}
else {
newLunghezza = l;//altrimenti è uguale a l
}
char *ptrTmpStringa = new char[newLunghezza + 1];//c'è sempre il carattere di terminazione
//copio la sottostringa nell'area di memoria a lei dedicata
strncpy(ptrTmpStringa, &ptrStringa[n], newLunghezza); //copio in ptrTempStringa la sottostringa di ptrStringa lunga newLunghezza partendo dalla posizione n
ptrTmpStringa[newLunghezza] = '\0';//aggiungo il carattere di terminazione
//creo per copia l'oggetto Tmpstringa
Stringhetta tmpStringa(ptrTmpStringa);//richiamo il costruttore
delete[] ptrTmpStringa;//cancello l'array temporaneo (la sottostringa è oramai salva in tmpStringa
return tmpStringa; //ritorno una copia della Stringhetta temporanea
}
int main()
{
Stringhetta k="ciao mondo";
Stringhetta m=" bello ";
Stringhetta j;
k+=m;
cout<<k<<endl;
if(k==j)
cout<<"Uguali\n";
cin>>k;
k[0]='Q';
cout<<k[3]<<endl;
cout<<k<<endl;
Stringhetta t;
string s="ciaoesvgfngmyumyu,i";
for(int i=0;i<4;i++)
t+=s[i];
cout<<t<<endl;
s[0]='Q';
cout<<t<<endl;
Stringhetta d("ciao");
if(d==t)
cout<<"Uguali\n";
}
Post Views: 602