Classe cstring

Soyez le premier à donner votre avis sur cette source.

Vue 9 823 fois - Téléchargée 260 fois

Description

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())

  • this = s->_pstr;
} CString(const CString &s) { this->_pstr = NULL; this->_size = 0; if(s.GetLength())
  • this = s._pstr;
} 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) {
  • this = s->_pstr;
return (*this); } CString& operator = (const CString &s) {
  • this = s._pstr;
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) {
  • this += s->_pstr;
return (*this); } CString& operator += (const CString &s) {
  • this += s._pstr;
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

Codes Sources

A voir également

Ajouter un commentaire Commentaires
Messages postés
16
Date d'inscription
lundi 9 août 2004
Statut
Membre
Dernière intervention
13 septembre 2004

Voila, j'ai fait la modification sur ma CString pour utiliser les headers C++ ;)
Messages postés
3011
Date d'inscription
jeudi 26 septembre 2002
Statut
Membre
Dernière intervention
27 novembre 2004
8
"alors pourquoi avoir créé iostream.h, pour ensuite dire que c'est deprecated?"

parce que ca n'est pas standard ! iostream.h ca date de l'epoque du c++ pre standard (avant 97), c'est deprecié et ca va disparaitre au prochain standard

maintenant tout est dans le namespace standard, meme lib standard c
Messages postés
16
Date d'inscription
lundi 9 août 2004
Statut
Membre
Dernière intervention
13 septembre 2004

Wow, y a du message ici !
Juste un petit mot au sujet des librairies "C" qui sont deprecated.. J'ai juste a remplacer iostream.h par iostream, et les librairies C classiques par leurs equivalents C++ comme je l'avais dit.. Ca change franchement pas grand chose, d'ailleurs c'est deprecated parce qu'ils ont envie que ca soit deprecated... D'ailleurs, est-ce que iostream existe en C? Je dirais que non, alors pourquoi avoir créé iostream.h, pour ensuite dire que c'est deprecated? :)

Bon en tout cas quand j'aurai le temps, je mettrai mes libs à jour pour prendre en compte tes remarques, djl, ca ne me coute absolument rien de toute facon! Sauf cinq minutes de mon temps pour changer quelques include ;)

++
Soilwork
PS : J'avais pas regardé qui était l'auteur du document. Si c'est le createur du C++, alors ok, il a le droit de faire le boss lol! Je retire ce que j'ai dit sur l'aspect pédant du texte :)
Messages postés
1878
Date d'inscription
jeudi 16 octobre 2003
Statut
Membre
Dernière intervention
16 mars 2011
1
en fait les CString étaient décrétés prioritaires sur mes BString sans causé de conflit

un bug amené par les modfis récentes : const:

les CString prenaient en charge la comparaison avec un caractere =>

résolu en rajoutant ceci ds le header
//deb: rajouté pr régler PB avec les MFC
du coup, pr résoudre ce pb, G inclu ds Visual uniquement les lignes suivantes ds le header.

bool operator==(const char s)const{return operator==((BString) s);}


par ex pr cet opérateur: le suivant était choisi
(syntaxe ptet approximative)

friend bool operator(const char& ,const CString&)const


vu que rien ne laissait présagé de cette erreur... ben détecté il y a une semaine seulement...


y avait une différence ! la comparaison de la casse !
voilu
++
Nono.
Messages postés
3011
Date d'inscription
jeudi 26 septembre 2002
Statut
Membre
Dernière intervention
27 novembre 2004
8
ouai je viens de voir ton exemple

> tout ce qui est inliner devrais pas poser de probleme

je repete, ce n'est pas un conseil que je donne, je dis juste que tes fonction inline doivent etre definie dans un header (si tu veut qu'elles soit sytematiquement inliner)

c'etait quoi le bug avec les bstring ?
Afficher les 33 commentaires

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.