Une classe CString gérée par allocation dynamique, opérateurs de concaténation, de copie, de comparaisons et méthodes de comparaison (case sensitive ou non)
petite optimisation vitesse : si on remplace une chaine par une autre plus petite, il n'y a pas de réallocation ce qui réduit les traitements et la fragmentation de la mémoire
Source / Exemple :
#ifndef __HCString__
#define __HCString__
#include "cstring"
#include "cstdlib"
class CString {
public:
CString() { // Constructeurs
this->_pstr = NULL;
this->_size = 0;
}
CString(long taille) { // constructeur avec préallocation
if(taille > 0) {
this->_alloc(taille);
this->_pstr[0] = 0;
} else {
this->_pstr = NULL;
this->_size = 0;
}
}
CString(const char *chaine) {
if(chaine) {
this->_alloc(strlen(chaine)+1);
strcpy(this->_pstr,chaine);
} else {
this->_pstr = NULL;
this->_size = 0;
}
}
CString(const CString *s) {
this->_pstr = NULL;
this->_size = 0;
if(s->GetLength())
}
CString(const CString &s) {
this->_pstr = NULL;
this->_size = 0;
if(s.GetLength())
}
CString( unsigned long lengthfromstart,const char *chaine) { // crée une chaine à partir d'une autre chaine en prenant les lengthfromstart caractères en début de chaine
if((chaine)&&(lengthfromstart>0)) {
this->_size = strlen(chaine);
if(lengthfromstart > this->_size) lengthfromstart = this->_size;
this->_alloc(lengthfromstart+1);
unsigned long i=0;
for(; i < lengthfromstart ;i++)
this->_pstr[i]=chaine[i];
this->_pstr[i] = 0;
} else {
this->_pstr = NULL;
this->_size = 0;
}
}
CString(const char *chaine, unsigned long lengthfromend) { // crée une chaine à partir d'une autre chaine en prenant les lengthfromend caractères en fin de chaine
if((chaine)&&(lengthfromend>0)) {
this->_size = strlen(chaine);
if(lengthfromend > this->_size) lengthfromend = this->_size;
this->_pstr = new char[lengthfromend+1];
strcpy(this->_pstr,&chaine[this->_size-lengthfromend]);
this->_size = lengthfromend+1;
} else {
this->_pstr = NULL;
this->_size = 0;
}
}
~CString() { // Destructeur
if(this->_pstr)
delete[] this->_pstr;
}
long GetLength(void) const { // Retourne la longueur d'une chaine (nombre de caractères, fin de chaine non inclus)
if(!this->_pstr) return 0;
return strlen(this->_pstr);
}
long GetSize(void) const { // retourne la taille du buffer alloué pour le stockage de chaine
return this->_size;
}
bool IsEmpty(void) const { // Retourne vrai si la chaine est vide
if(!this->_pstr) return true;
return (this->_pstr[0]==0);
}
void Empty(void) { // Met la chaine à une longueur de 0
if(this->_pstr)
this->_pstr[0] = 0;
}
// Comparaisons (retourne true si identiques, sinon false)
bool Compare(const char *chaine) const { // case sensitive
long l=this->GetLength();
if((!chaine)||(!l)) return false;
if ((long)strlen(chaine) != l) return false;
for (;(l>=0)&&(this->_pstr[l]==chaine[l]);l--);
return l<0;
}
bool Compare(const CString *chaine) const {
return this->Compare(chaine->_pstr);
}
bool Compare(const CString &chaine) const {
return this->Compare(chaine._pstr);
}
bool CompareNoCase(const char *chaine) const { // case insensitive
long l=this->GetLength();
if((!chaine)||(!l)) return false;
if ((long)strlen(chaine) != l) return false;
CString src = *this;
CString test = CString(chaine);
src.MakeLower();
test.MakeLower();
for (;(l>=0)&&(src._pstr[l]==test._pstr[l]);l--);
return l<0;
}
bool CompareNoCase(const CString *chaine) const {
return this->CompareNoCase(chaine->_pstr);
}
bool CompareNoCase(const CString &chaine) const {
return this->CompareNoCase(chaine._pstr);
}
void MakeUpper(void) { // Convertit la chaine en majuscules
long l=this->GetLength();
if(!l) return;
for(;l>=0;l--)
if((this->_pstr[l] >= 97)&&(this->_pstr[l] <= 122))
this->_pstr[l] -= 32;
}
void MakeLower(void) { // convertit la chaine en minuscules
long l=this->GetLength();
if(!l) return;
for(;l>=0;l--)
if((this->_pstr[l] >= 65)&&(this->_pstr[l] <= 90))
this->_pstr[l] += 32;
}
void MakeReverse(void) { // Inverse la chaine (debut<->fin)
long l = this->GetLength();
long i = (l>>1)+(l&0x1);
char tmp;
for(l=(l>>1)-1;l>=0;l--,i++) {
tmp = this->_pstr[l];
this->_pstr[l] = this->_pstr[i];
this->_pstr[i] = tmp;
}
}
long FindFromStart(char c) { // renvoie l'indice où le premier caractère 'c' est positionné dans la chaine
long l=this->GetLength();
long i=0;
for(; ((i<l)&&(this->_pstr[i]!=c));i++);
return (i==l)?l:i;
}
long FindFromEnd(char c) { // renvoie l'indice où le dernier caractère 'c' est positionné dans la chaine
long l=this->GetLength();
long i=l-1;
for(; ((i>=0)&&(this->_pstr[i]!=c));i--);
return (i==l)?l:i;
}
CString& Cut(long start,long end=0) {
long l = this->GetLength();
if(start>l) start = l;
if(!end) end = l;
if(end < start) end = start;
if(end > l) end = l;
long i=0;
for(;start <= end;start++,i++)
this->_pstr[i] = this->_pstr[start];
return (*this);
}
/////////////////////
// Les opérateurs //
/////////////////////
CString& operator = (const char *s) {
if(!s) return (*this);
unsigned long l = strlen(s);
if(!l) return (*this);
if(this->_size <= l)
this->_realloc(l+1);
strcpy(this->_pstr,s);
this->_pstr[l] = 0;
return (*this);
}
CString& operator = (const CString *s) {
return (*this);
}
CString& operator = (const CString &s) {
return (*this);
}
CString& operator + (const char *s) {
int l1 = this->GetLength();
int l2 = strlen(s);
if(l1+l2 == 0) return (*this);
CString *newchaine = new CString(l1+l2+1);
- newchaine = this->_pstr;
- newchaine += s;
return (*newchaine);
}
CString& operator + (const CString *s) { return *this + s->_pstr; }
CString& operator + (const CString &s) { return *this + s._pstr; }
CString& operator += (const char *s) {
if(!s) return (*this);
unsigned long l1=this->GetLength();
unsigned long l2=strlen(s);
if(this->_size <= (l1+l2)) {
char *newchaine = new char[l1+l2+1];
strcpy(newchaine,this->_pstr);
delete[] this->_pstr;
this->_pstr = newchaine;
this->_size = l1+l2+1;
}
strcpy(&this->_pstr[l1],s);
return (*this);
}
CString& operator += (const CString *s) {
return (*this);
}
CString& operator += (const CString &s) {
return (*this);
}
bool operator == (const char *s) const { return this->Compare(s); }
bool operator == (const CString *s) const { return this->Compare(s->_pstr); }
bool operator == (const CString &s) const { return this->Compare(s._pstr); }
bool operator != (const char *s) const { return !this->Compare(s); }
bool operator != (const CString *s) const { return !this->Compare(s->_pstr); }
bool operator != (const CString &s) const { return !this->Compare(s._pstr); }
operator char*() { return this->_pstr; }
operator const char*() const { return this->_pstr; }
char &operator[](int _i) { return this->_pstr[_i]; }
const char &operator[](int _i) const { return this->_pstr[_i]; }
private:
void _alloc(unsigned long taille) {
this->_pstr = new char[taille];
this->_size = taille;
}
void _realloc(unsigned long taille) {
if(this->_pstr) delete[] this->_pstr;
this->_pstr = new char[taille];
this->_size = taille;
}
char *_pstr; // le pointeur pour le buffer contenant la chaine
unsigned long _size; // la taille de la dernière allocation
};
#endif // __HCString__
Conclusion :
Comme tout programme (surtout les miens ;-p) celui ci n'est pas parfait, tous commentaires de type critique (constructive svp) ou visant à la correction de bug ou à l'amélioration sont bienvenus
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.