Vous pouvez r�cup�rer tous les programmes en un seul tar.gz sur Telecharger String . Pour obtenir ce fichier, dans un butineur web, sauvez ce fichier en type 'texte'.
// // Auteur : Al Dev // Utilisez la classe string ou cette classe // // Pour pr�venir les fuites de m�moire - une classe caract�re qui g�re les // variables caract�res. // Pr�f�rez toujours l'utilisation de la classe string � char[] et char *. // // // Pour compiler et tester ce programme, utilisez - // g++ String.cpp #include "String.h" //#include <sys/va_list.h> pour Format() //#include <sys/varargs.h> pour Format() // Variables globales.... //String *String::_global_String = NULL; // variable globale list<String> String::explodeH; String::String() { debug_("In cstr()", "ok"); sval = (char *) my_malloc(sizeof(char)* INITIAL_SIZE); _pString = NULL; } String::String(char *bb) { unsigned long tmpii = strlen(bb); sval = (char *) my_malloc(sizeof(char)* tmpii); strncpy(sval, bb, tmpii); sval[tmpii] = '\0'; //debug_("In cstr(char *bb) bb", bb); debug_("In cstr(char *bb) sval", sval); #ifdef DEBUG //fprintf(stderr, "\nAddress of sval=%x\n", & sval); //fprintf(stderr, "\nAddress of this-pointer=%x\n", this); #endif // DEBUG _pString = NULL; } String::String(char *bb, int start, int slength) { unsigned long tmpii = strlen(bb); if (start> (int) tmpii || start < 0) { cerr << "\nString(char *, int, int) - start is out of bounds!!\n" << endl; exit(1); } sval = (char *) my_malloc(sizeof(char)* slength); strncpy(sval, & bb[start], slength); sval[slength] = '\0'; //debug_("In cstr(char *bb) bb", bb); debug_("In cstr(char *bb) sval", sval); #ifdef DEBUG //fprintf(stderr, "\nAddress of sval=%x\n", & sval); //fprintf(stderr, "\nAddress of this-pointer=%x\n", this); #endif // DEBUG _pString = NULL; } String::String(int bb) { sval = (char *) my_malloc(NUMBER_LENGTH); // int avec 70 chiffres max sprintf(sval, "%d", bb); debug_("In cstr(int bb) sval", sval); _pString = NULL; } String::String(unsigned long bb) { sval = (char *) my_malloc(NUMBER_LENGTH); // unsigned long avec 70 chiffres max sprintf(sval, "%lu", bb); debug_("In cstr(unsigned long bb) sval", sval); _pString = NULL; } String::String(long bb) { sval = (char *) my_malloc(NUMBER_LENGTH); // long avec 70 chiffres max sprintf(sval, "%ld", bb); debug_("In cstr(long bb) sval", sval); _pString = NULL; } String::String(float bb) { sval = (char *) my_malloc(NUMBER_LENGTH); // float avec 70 chiffres max sprintf(sval, "%f", bb); debug_("In cstr(float bb) sval", sval); _pString = NULL; } String::String(double bb) { sval = (char *) my_malloc(NUMBER_LENGTH); // double avec 70 chiffres max sprintf(sval, "%f", bb); debug_("In cstr(double bb) sval", sval); _pString = NULL; } // Constructeur par recopie utilis� par l'op�rateur + String::String(const String & rhs) { // Effectue une copie en profondeur � la place de la copie superficielle par d�faut du compilateur debug_("In copy-cstr()", "ok"); unsigned long tmpii = strlen(rhs.sval); sval = (char *) my_malloc(sizeof(char)* tmpii); strncpy(sval, rhs.sval, tmpii); sval[tmpii] = '\0'; _pString = NULL; } // Cette fonction fournit une compatibilit� avec le code Java String::String(StringBuffer sb) { debug_("In String(StringBuffer)", "ok"); unsigned long tmpii = strlen(sb.sval); sval = (char *) my_malloc(sizeof(char)* tmpii); strncpy(sval, sb.sval, tmpii); sval[tmpii] = '\0'; _pString = NULL; } // Utilis� par la classe StringBuffer. Utilise la variable dummy // pour diff�rentes signatures. // La classe StringBuffer imite le StringBuffer de Java String::String(int size, bool dummy) { sval = (char *) my_malloc(sizeof(char)* size); debug_("In cstr(int size, bool dummy) sval", sval); #ifdef DEBUG //fprintf(stderr, "\nAddress of sval=%x\n", & sval); //fprintf(stderr, "\nAddress of this-pointer=%x\n", this); #endif // DEBUG _pString = NULL; } String::~String() { debug_("In dstr sval", sval); #ifdef DEBUG //fprintf(stderr, "\nAddress of sval=%x\n", & sval); //fprintf(stderr, "\nAddress of this-pointer=%x\n", this); #endif // DEBUG my_free(sval); //delete [] sval; sval = NULL; delete _pString; _pString = NULL; } inline void String::_allocpString() { // _pString will be deleted in destructor if (!_pString) // if (_pString == NULL) _pString = new String(this->sval); else *_pString = this->sval; } // DOIT utiliser un pointeur-sur-pointeur **aa, sinon la m�moire utilis�e // par l'argument N'est PAS lib�r�e ! /* inline void String::_free_glob(String **aa) { debug_("called _free_glob()", "ok" ); if (*aa != NULL) // (*aa != NULL) { debug_("*aa is not null", "ok"); delete *aa; *aa = NULL; } //else debug_("*aa is null", "ok"); //if (*aa == NULL) debug_("*aa set to null", "ok"); } */ // Imite le charAt de java.lang.String char String::charAt(int where) { verifyIndex(where); return (sval[where]); } // Imite la fonction getChars de java.lang.String // sourceStart sp�cifie l'indice du d�but de la sous-cha�ne // et sourceEnd sp�cifie l'indice juste apr�s la fin de la sous-cha�ne d�sir�e // Ainsi la sous-cha�ne contient les caract�res de sourceStart jusqu'� // (sourceEnd - 1). Le tableau qui va recevoir les caract�res est target. // targetStart est l'indice dans target � partir duquel la copie sera effectu�e. // Il convient de s'assurer que le tableau target est assez grand pour pouvoir contenir // le nombre de caract�res d�sir�. // Par exemple getChars(3, 6, aa, 0) sur "ABCDEFGHIJK" donne aa ="DEF" void String::getChars(int sourceStart, int sourceEnd, char target[], int targetStart) { verifyIndex(sourceStart); verifyIndex(sourceEnd); if (sourceEnd>= sourceStart) { strncpy(& target[targetStart], & sval[sourceStart], sourceEnd - sourceStart); target[targetStart + (sourceEnd - sourceStart)] = 0; } else { cerr << "\ngetChars() - SourceEnd is greater than SourceStart!!\n" << endl; exit(1); } } // Imite getChars de java.lang.String // Retourne un tableau caract�res contenant la cha�ne enti�re char* String::toCharArray() { return (sval); } // Imite getBytes de java.lang.String // Retourne un tableau caract�res contenant la cha�ne enti�re char* String::getBytes() { return (sval); } // Imite equals de java.lang.String bool String::equals(String str2) // voir aussi l'op�rateur == { return ( _equalto(str2.sval)); } // Imite equals de java.lang.String bool String::equals(char *str2) // voir aussi l'op�rateur == { return ( _equalto(str2)); } // Imite equalsIgnoreCase de java.lang.String bool String::equalsIgnoreCase(String str2) { String aa, bb; aa = this->toLowerCase(); bb = str2.toLowerCase(); return ( aa._equalto(bb.sval) ); } // Imite regionMatches de java.lang.String // startIndex sp�cifie l'indice � partir duquel d�bute la r�gion dans l'objet // String invoquant la m�thode. La cha�ne est compar�e � str2. L'indice � partir // duquel la comparaison commencera dans str2 est sp�cifi� par str2Index // La longueur de la sous-cha�ne compar�e est numChars. bool String::regionMatches(int startIndex, String str2, int str2StartIndex, int numChars) { verifyIndex(startIndex); str2.verifyIndex(str2StartIndex); if (strncmp(& this->sval[startIndex], & str2.sval[str2StartIndex], numChars) == 0) return true; else return false; } // Imite regionMatches de java.lang.String // Il s'agit de la version surcharg�e de regionMatches // Si ignoreCase vaut true, la casse des caract�res est ignor�e, sinon // la casse est significative (i.e. si ignoreCase vaut true alors ignore la // casse et compare) // startIndex sp�cifie l'indice � partir duquel d�bute la region dans l'objet // String invoquant la m�thode. La cha�ne est compar�e � str2. L'indice � partir // duquel la comparaison commencera dans str2 est sp�cifi� par str2Index // La longueur de la sous-cha�ne compar�e est numChars. bool String::regionMatches(bool ignoreCase, int startIndex, String str2, int str2StartIndex, int numChars) { if (ignoreCase) // if (ignoreCase == true) { verifyIndex(startIndex); str2.verifyIndex(str2StartIndex); String string1, string2; string1 = this->toLowerCase(); string2 = str2.toLowerCase(); if (strncmp(& string1.sval[startIndex], & string2.sval[str2StartIndex], numChars) == 0) return true; else return false; } else { return regionMatches(startIndex, str2, str2StartIndex, numChars); } } // Imite toLowerCase de java.lang.String // String ss("sometest"); // String egg = ss.toLowerCase(); String String::toLowerCase() { _allocpString(); for (long tmpii = strlen(_pString->sval); tmpii>= 0; tmpii--) { _pString->sval[tmpii] = tolower(_pString->sval[tmpii]); } return *_pString; // return the object now } // Imite toUpperCase de java.lang.String // String ss("sometest"); // String egg = ss.toUpperCase(); String String::toUpperCase() { _allocpString(); for (long tmpii = strlen(_pString->sval); tmpii>= 0; tmpii--) { _pString->sval[tmpii] = toupper(_pString->sval[tmpii]); } return *_pString; // return the object now } // Imite startsWith de java.lang.String bool String::startsWith(String str2) { if (!strncmp(this->sval, str2.sval, strlen(str2.sval) )) // if (strncmp() == 0) return true; else return false; } // Imite startsWith de java.lang.String // Fonction surcharg�e bool String::startsWith(char *str2) { int lenstr2 = strlen(str2); if (!strncmp(this->sval, str2, lenstr2)) // if (strncmp() == 0) return true; else return false; } // Imite endsWith de java.lang.String bool String::endsWith(String str2) { // str2 doit �tre plus courte que la cha�ne courante if (strlen(str2.sval)> strlen(sval)) return false; if (!strncmp(& this->sval[strlen(sval) - strlen(str2.sval)], str2.sval, strlen(str2.sval) )) // if (strncmp() == 0) return true; else return false; } // Imite endsWith de java.lang.String bool String::endsWith(char *str2) { // str2 doit �tre plus courte que la cha�ne courante if (strlen(str2)> strlen(sval)) return false; if (!strncmp(& this->sval[strlen(sval) - strlen(str2)], str2, strlen(str2) ) ) // if (strncmp() == 0) return true; else return false; } // Imite compareTo de java.lang.String // Pour les tris, vous devez savoir si l'un est plus petit, �gal ou plus grand que l'autre. // Une cha�ne est plus petite qu'une autre si elle arrive avant l'autre dans l'ordre // lexicographique. Un cha�ne est plus grande qu'une autre si elle arrive apr�s. // N�gatif --> la cha�ne courante est plus petite que str2 // Positif --> la cha�ne courante est plus grande que str2 // Zero --> les deux cha�nes sont �gales int String::compareTo(String str2) { int flag = 0; // Compare les lettres dans la cha�ne � chaque lettre de str2 for (int tmpii = 0, tmpjj = strlen(sval), tmpkk = strlen(str2.sval); tmpii < tmpjj; tmpii++) { if (tmpii> tmpkk) break; if (sval[tmpii] == str2.sval[tmpii]) flag = 0; else if (sval[tmpii]> str2.sval[tmpii]) { flag = 1; break; } else // if (sval[tmpii] < str2.sval[tmpii]) { flag = -1; break; } } return flag; } // Imite compareTo de java.lang.String // Fonction surcharg�e de compareTo int String::compareTo(char *str2) { int flag = 0; // Compare les lettres de la cha�ne courante avec chaque lettre de str2 for (int tmpii = 0, tmpjj = strlen(sval), tmpkk = strlen(str2); tmpii < tmpjj; tmpii++) { if (tmpii> tmpkk) break; if (sval[tmpii] == str2[tmpii]) flag = 0; else if (sval[tmpii]> str2[tmpii]) { flag = 1; break; } else // if (sval[tmpii] < str2[tmpii]) { flag = -1; break; } } return flag; } // Imite compareToIgnoreCase de java.lang.String int String::compareToIgnoreCase(String str2) { String tmpaa = this->toLowerCase(), tmpbb = str2.toLowerCase(); return tmpaa.compareTo(tmpbb); } // Imite compareToIgnoreCase de java.lang.String // Version surcharg�e int String::compareToIgnoreCase(char *str2) { String tmpaa = this->toLowerCase(), tmpcc(str2), tmpbb = tmpcc.toLowerCase(); return tmpaa.compareTo(tmpbb); } // Imite indexOf de java.lang.String // Cherche la premiere occurrence d'un caract�re ou d'une cha�ne. // Retourne l'indice � partir duquel le caract�re ou la cha�ne // a �t� trouv�, ou -1 en cas d'�chec. int String::indexOf(char ch, int startIndex = 0) { verifyIndex(startIndex); int ii = startIndex; for (; ii < (int) strlen(sval); ii++) { if (sval[ii] == ch) break; } if (ii == (int) strlen(sval)) return -1; return ii; } // Imite indexOf de java.lang.String // Version surcharg�e int String::indexOf(char *str2, int startIndex = 0) { verifyIndex(startIndex); char * tok; long res = -1; if ( !isNull() ) { tok = strstr(sval + startIndex, str2); if (tok == NULL) res = -1; else res = (int) (tok - sval); } return res; } // Imite indexOf de java.lang.String // Version surcharg�e int String::indexOf(String str2, int startIndex = 0) { verifyIndex(startIndex); char * tok; long res = -1; if ( !isNull() ) { tok = strstr(sval + startIndex, str2.sval); if (tok == NULL) res = -1; else res = (int) (tok - sval); } return res; } // Imite lastIndexOf de java.lang.String // Cherche pour la derni�re occurrence d'un caract�re ou d'une cha�ne. // Retourne l'indice � partir duquel le caract�re ou la cha�ne a �t� trouv� // ou -1 en cas d'�chec. int String::lastIndexOf(char ch, int startIndex = 0) { verifyIndex(startIndex); int ii; // Commence la recherche par le dernier caract�re de la cha�ne if (!startIndex) // if (startIndex == 0) ii = strlen(sval); else ii = startIndex; for (; ii> -1; ii--) { if (sval[ii] == ch) break; } if (!ii && sval[ii] != ch) // if (ii == 0) return -1; return ii; } // Imite lastIndexOf de java.lang.String // Version surcharg�e int String::lastIndexOf(char *str2, int startIndex = 0) { verifyIndex(startIndex); char *tok = NULL; int res = -1; register char *tmpaa = strdup(sval); // ici malloc if (!tmpaa) // tmpaa == NULL { cerr << "\nMemory alloc failed in strdup in lastIndexOf()\n" << endl; exit(-1); } if (!startIndex) // if (startIndex == 0) startIndex = strlen(sval); else tmpaa[startIndex+1] = 0; for (int ii = 0; ii <= startIndex; ii++) { tok = strstr(& tmpaa[ii], str2); if (tok == NULL) break; else { res = (int) (tok - tmpaa); debug_("res", res); ii = res; // saute vers l'endroit qui correspond (+1 dans la boucle for) } } free(tmpaa); debug_("res", res); debug_("indexOf", & sval[res]); return res; } // Imite lastIndexOf de java.lang.String // Version surcharg�e int String::lastIndexOf(String str2, int startIndex = 0) { verifyIndex(startIndex); char *tok = NULL; int res = -1; register char *tmpaa = strdup(sval); // ici malloc if (!tmpaa) // tmpaa == NULL { cerr << "\nMemory alloc failed in strdup in lastIndexOf()\n" << endl; exit(-1); } if (!startIndex) // if (startIndex == 0) startIndex = strlen(sval); else tmpaa[startIndex+1] = 0; for (int ii = 0; ii <= startIndex; ii++) { tok = strstr(& tmpaa[ii], str2.sval); if (tok == NULL) break; else { res = (int) (tok - tmpaa); debug_("res", res); ii = res; // saute vers l'endroit qui correspond (+1 dans la boucle for) } } free(tmpaa); debug_("res", res); debug_("indexOf", & sval[res]); return res; } // Imite substring de java.lang.String // startIndex sp�cifie l'indice de d�but, et endIndex l'indice de fin. // La cha�ne retourn�e contient tous les caract�res de l'indice de d�but // jusqu'� l'indice de fin, mais sans l'inclure. String String::substring(int startIndex, int endIndex = 0) { String tmpstr = String(sval); tmpstr._substring(startIndex, endIndex); return tmpstr; } // Imite concat de java.lang.String String String::concat(String str2) { return (*this + str2); } // Imite concat de java.lang.String // Version surcharg�e String String::concat(char *str2) { return (*this + str2); } // Imite replace de java.lang.String // Remplace toutes les occurrences de la cha�ne 'original' par // 'replacement' dans 'sval' String String::replace(char original, char replacement) { // Par exemple - // replace('A', 'B') dans sval = "des AAA et AAACC" // retourne sval = "des BBB et BBBCC" //String *tmpstr = new String(sval); Utilise le constructeur de recopie par d�faut String tmpstr(sval); for (int ii = 0, len = strlen(sval); ii < len; ii++) { if (tmpstr.sval[ii] == original) tmpstr.sval[ii] = replacement; } return tmpstr; // utilise le constructeur de recopie pour faire une copie } // Imite replace de java.lang.String // Version surcharg�e // Remplace toutes les occurrences de la cha�ne 'original' par // 'replacement' dans 'sval' String String::replace(char *original, char *replacement) { char *tok = NULL, *bb; register char *aa = strdup(sval); int lenrepl = strlen(replacement); // Alloue l'espace pour bb { // port�e locale int tmpii = 0; for (int ii = 0; ;ii++) { tok = strstr(& aa[ii], original); if (tok == NULL) break; else { ii = ii + (int) (tok -aa); tmpii++; } } if (!tmpii) // tmpii == 0, pas de 'original' trouv� return (String(sval)); // retourne la cha�ne originale tmpii = strlen(sval) + (tmpii * lenrepl) + 20; debug_("strstr tmpii", tmpii ); bb = (char *) malloc(tmpii); memset(bb, 0, tmpii); } for (int res = -1; ;) { debug_("aa", aa); tok = strstr(aa, original); if (tok == NULL) { strcat(bb, aa); break; } else { res = (int) (tok - aa); strncat(bb, aa, res); strcat(bb, replacement); //bb[strlen(bb)] = 0; debug_("res", res ); debug_("bb", bb ); strcpy(aa, & aa[res+lenrepl]); } } debug_("bb", bb ); free(aa); String tmpstr(bb); free(bb); return tmpstr; } /* une autre m�thode pour faire le remplacement mais lente... String String::replace(char *original, char *replacement) { // Par exemple - // replace("AAA", "BB") avec sval = "des AAA et AAACC" // retourne sval = "des BB et BBCC" String bb(this->before(original).sval); if (strlen(bb.sval) == 0) return String(sval); // retourne la cha�ne originale bb += replacement; String tmpaa(this->sval), cc, dd; for (;;) { cc = tmpaa.after(original).sval; debug_("cc", cc.sval ); if (!strlen(cc.sval)) // if (strlen(cc.sval) == 0) break; dd = cc.before(original).sval; if (strlen(dd.sval) == 0) { bb += cc; break; } else { bb += dd; bb += replacement; } tmpaa = cc; } debug_("bb.sval", bb.sval ); return bb; } */ // Imite replace de Java - StringBuffer String String::replace (int startIndex, int endIndex, String str) { verifyIndex(startIndex); verifyIndex(endIndex); int tmpjj = strlen(str.sval); if (tmpjj == 0) return *this; int tmpii = endIndex-startIndex-1; if (tmpjj < tmpii) // la longueur de str est plus petite que les indices specifies. tmpii = tmpjj; debug_("sval", sval); debug_("str.sval", str.sval); strncpy(& sval[startIndex], str.sval, tmpii); sval[startIndex+tmpii] = 0; debug_("sval", sval); return *this; } // Imite trim de java.lang.String String String::trim() { //String *tmpstr = new String(sval); String tmpstr(sval); tmpstr._trim(); debug_("tmpstr.sval", tmpstr.sval); return tmpstr; // utilise le constructeur par recopie pour faire une copie } // Imite insert de java.lang.String String String::insert(int index, String str2) { String tmpstr(this->insert(str2.sval, index).sval); debug_("tmpstr.sval", tmpstr.sval); return tmpstr; } // Imite insert de java.lang.String String String::insert(int index, char ch) { char aa[2]; aa[0] = ch; aa[1] = 0; String tmpstr(this->insert(aa, index).sval); debug_("tmpstr.sval", tmpstr.sval); return tmpstr; } // Imite deleteCharAt de java.lang.String String String::deleteCharAt(int loc) { String tmpstr(sval); tmpstr._deleteCharAt(loc); return tmpstr; } // Imite delete de java.lang.String // Note : -->le nom Java est "delete()", mais c'est un mot r�s�rv� inutilisable en C++ // startIndex sp�cifie l'indice du premier caract�re � enlever, // et endIndex l'indice juste apr�s le dernier caract�re � supprimer. // Ainsi, la sous-cha�ne supprim�e s'etend de startIndex � (endIndex - 1). String String::deleteStr(int startIndex, int endIndex) { // Par exemple - // deleteStr(3,3) avec val = 'pokemon' retourne 'poon' String tmpstr(sval); tmpstr._deleteStr(startIndex, endIndex); return tmpstr; } // Imite reverse de java.lang.String String String::reverse() { // Par exemple : // reverse() sur "12345" retourne "54321" String tmpstr(sval); tmpstr._reverse(); return tmpstr; } // Imite valueOf de java.lang.String String String::valueOf(char chars[], int startIndex, int numChars) { verifyIndex(startIndex); int ii = strlen(chars); if (startIndex> ii) { cerr << "\nvalueOf() - startIndex greater than string length of" << "string passed" << endl; exit(0); } if ( (numChars+startIndex)> ii) { cerr << "\nvalueOf() - numChars exceeds the string length of" << "string passed" << endl; exit(0); } char *aa = strdup(chars); aa[startIndex + numChars] = 0; String tmpstr(& aa[startIndex]); free(aa); return tmpstr; } // Imite ensureCapacity de java.lang.String // Utilis� par la classe StringBuffer. // Pr�-alloue la place pour un certain nombre de caract�res. // Utile si vous savez � l'avance que vous allez rajouter un grand nombre // de petites cha�nes � un StringBuffer void String::ensureCapacity(int capacity) { sval = (char *) my_realloc(sval, capacity); sval[0] = '\0'; debug_("In ensureCapacity(int capacity) sval", sval); } // Imite setLength de java.lang.String // Utilise par la classe StringBuffer. void String::setLength(int len) { sval = (char *) my_realloc(sval, len); sval[0] = '\0'; debug_("In ensureCapacity(int len) sval", sval); } // Imite setCharAt de StringBuffer void String::setCharAt(int where, char ch) { verifyIndex(where); sval[where] = ch; debug_("in StringBuffer dstr()", "ok"); } // ---- Fin des fonctions imitant java.lang.String ----- // Version surcharg�e, modifie directement l'objet // La variable dummy donne une signature diff�rente � la fonction. void String::substring(int startIndex, int endIndex, bool dummy) { this->_substring(startIndex, endIndex); } inline void String::_substring(int startIndex, int endIndex) { verifyIndex(startIndex); verifyIndex(endIndex); if (!endIndex) // endIndex == 0 strcpy(sval, & sval[startIndex] ) ; else { if (endIndex> startIndex) { strcpy(sval, & sval[startIndex] ) ; sval[endIndex -startIndex] = 0; } else { cerr << "\n_substring() - startIndex is greater than endIndex!!\n" << endl; exit(-1); } } } // Version surcharg�e, modifie directement l'objet String String::deleteStr(int startIndex, int endIndex, bool dummy) { this->_deleteStr(startIndex, endIndex); return *this; } inline void String::_deleteStr(int startIndex, int endIndex) { verifyIndex(startIndex); verifyIndex(endIndex); // Par exemple - // deleteStr(3,3) avec val = 'pokemon' retourne 'poon' char *tmpaa = strdup(sval); // ici malloc strcpy(& tmpaa[startIndex], & tmpaa[endIndex]); *this = tmpaa; free(tmpaa); } // Version surcharg�e, modifie directement l'objet String String::deleteCharAt(int loc, bool dummy) { this->_deleteCharAt(loc); return *this; } inline void String::_deleteCharAt(int loc) { char *tmpaa = strdup(sval); // ici malloc strcpy(& tmpaa[loc], & tmpaa[loc+1]); *this = tmpaa; free(tmpaa); } // Retourne la cha�ne avant regx. Trouve la premi�re occurrence de regx. String String::at(char *regx) { char *tok = NULL; tok = strstr(sval, regx); if (tok == NULL) return(String("")); else { int res = (int) (tok - sval); char *lefttok = strdup(sval); memset(lefttok, 0, strlen(sval)); strcpy(lefttok, & sval[res]); String tmpstr(lefttok); free(lefttok); return(tmpstr); } } // Retourne la cha�ne avant regx. Trouve la premi�re occurrence de regx. String String::before(char *regx) { char *tok = NULL; tok = strstr(sval, regx); if (tok == NULL) return(String("")); else { int res = (int) (tok - sval); char *lefttok = strdup(sval); lefttok[res] = 0; String tmpstr(lefttok); free(lefttok); return(tmpstr); } } // Retourne la cha�ne apr�s regx. Trouve la premi�re occurrence de regx. String String::after(char *regx) { char *tok = NULL; tok = strstr(sval, regx); if (tok == NULL) return(String("")); else { int res = (int) (tok - sval); char *lefttok = strdup(sval); memset(lefttok, 0, strlen(sval)); strcpy(lefttok, & sval[res + strlen(regx)]); String tmpstr(lefttok); free(lefttok); return(tmpstr); } } // Divise la cha�ne et retourne une liste via le pointeur de t�te // de liste explodeH. // Voir aussi token(). void String::explode(char *seperator) { char *aa = NULL, *bb = NULL; aa = (char *) my_malloc(strlen(sval)); for (bb = strtok(aa, seperator); bb != NULL; bb = strtok(NULL, seperator) ) { String *tmp = new String(bb); String::explodeH.insert(String::explodeH.end(), *tmp); } my_free(aa); list<String>::iterator iter1; // voir include/g++/stl_list.h debug_("Before checking explode..", "ok"); if (String::explodeH.empty() == true ) { debug_("List is empty!!", "ok"); } for (iter1 = String::explodeH.begin(); iter1 != String::explodeH.end(); iter1++) { if (iter1 == NULL) { debug_("Iterator iter1 is NULL!!", "ok" ); break; } debug_("(*iter1).sval", (*iter1).sval); } } // Version surcharg�e de explode(). Retourne un tableau // de cha�nes et le nombre total dans la r�f�rence strcount // Voir aussi token(). String *String::explode(int & strcount, char seperator = ' ') { String aa(sval); aa.trim(true); strcount = 0; for (int ii = 0, jj = strlen(aa.sval); ii < jj; ii++) { if (aa.sval[ii] == seperator) strcount++; } String *tmpstr = new String[strcount+1]; if (!strcount) // strcount == 0 tmpstr[0] = aa.sval; else { for (int ii = 0; ii <= strcount; ii++) tmpstr[ii] = aa.token(); } return tmpstr; } // Agr�ge les cha�nes point�es par la t�te de liste // explodeH et retourne la classe String. void String::implode(char *glue) { } // Agr�ge les cha�nes point�es par la t�te de liste // explodeH et retourne la classe String. void String::join(char *glue) { implode(glue); } // R�p�te la cha�ne input n fois. String String::repeat(char *input, unsigned int multiplier) { // Pour exemple - // repeat("k", 4) retourne "kkkk" if (!input) // input == NULL { return (String("")); } char *aa = (char *) my_malloc(strlen(input) * multiplier); for (unsigned int tmpii = 0; tmpii < multiplier; tmpii++) { strcat(aa, input); } String tmpstr(aa); my_free(aa); return tmpstr; } // Renverse la cha�ne. // Version surcharg�e de reverse(). Modifie directement l'objet. void String::reverse(bool dummy) { this->_reverse(); } inline void String::_reverse() { // Par exemple - // reverse() sur "12345" retourne "54321" char aa; unsigned long tot_len = strlen(sval); unsigned long midpoint = tot_len / 2; for (unsigned long tmpjj = 0; tmpjj < midpoint; tmpjj++) { aa = sval[tmpjj]; // variable temporaire de stockage sval[tmpjj] = sval[tot_len - tmpjj - 1]; // permute les valeurs sval[tot_len - tmpjj - 1] = aa; // permute les valeurs } } // Change certain caract�res. // Par exemple ("abcd", "ABC") change toutes les occurrences de chaque // caract�re de 'from' en le caract�re correspondant dans 'to' String String::tr(char *from, char *to) { int lenfrom = strlen(from), lento = strlen(to); if (lento> lenfrom) lento = lenfrom; // choisit le min else if (lento < lenfrom) lenfrom = lento; // choisit le min debug_("lento", lento); register char *aa = strdup(sval); for (int ii = 0, jj = strlen(sval); ii < jj; ii++) // pour chaque caract�re dans val { for (int kk = 0; kk < lento; kk++) // pour chaque caract�re dans "from" { if (aa[ii] == from[kk]) aa[ii] = to[kk]; } } String tmpstr(aa); free(aa); return tmpstr; } // Centre le texte String String::center(int padlength, char padchar = ' ') { // Par exemple - // center(10, '*') avec sval="aa" retourne "****aa****" // center(10) avec sval="aa" retourne " aa " // Le r�sultat est une cha�ne contenant 'padlength' caract�res avec sval au milieu. int tmpii = sizeof(char) * (padlength + strlen(sval) + 10); char *aa = (char *) malloc(tmpii); memset(aa, 0, tmpii); for (int jj = 0, kk = (int) padlength/2; jj < kk; jj++) { aa[jj] = padchar; } strcat(aa, sval); for (int jj = strlen(aa), kk = jj + (int) padlength/2; jj < kk; jj++) { aa[jj] = padchar; } String tmpstr(aa); free(aa); return tmpstr; } // Formate la cha�ne originale en pla�ant <number> caract�res <padchar> // entre chaque ensemble de mots d�limit�s par des blancs. Les blancs en d�but et // en fin sont toujours supprim�s. Si <number> est omis ou vaut 0, alors tous les // espaces de la cha�ne sont supprim�s. Par d�faut, <number> vaut 0 et padchar ' '. String String::space(int number, char padchar = ' ') { // Par exemple - // space(3) avec sval = "Je ne sais pas" // retournera "Je ne sais pas" // space(1, '_') avec sval = "Un lieu profondement obscur" // retournera "Un_lieu_profondement_obscur" // space() avec sval = "Je sais cela" // retournera "Jesaiscela" debug_("this->sval", this->sval ); String tmpstr = this->trim().sval; debug_("tmpstr.sval", tmpstr.sval ); // compte les espaces int spacecount = 0; for (int ii = 0, jj = strlen(tmpstr.sval); ii < jj; ii++) { if (tmpstr.sval[ii] == ' ') spacecount++; } debug_("spacecount", spacecount); char ee[2]; ee[0] = padchar; ee[1] = 0; String bb = tmpstr.repeat(ee, spacecount); int tmpii = sizeof(char) * (strlen(tmpstr.sval) + (number * spacecount) + 20); char *aa = (char *) malloc(tmpii); memset(aa, 0, tmpii); for (int ii = 0, jj = strlen(tmpstr.sval); ii < jj; ii++) { if (tmpstr.sval[ii] == ' ') strcat(aa, bb.sval); else { ee[0] = sval[ii]; strcat(aa, ee); } } tmpstr = aa; free(aa); return tmpstr; } // Le r�sultat est une cha�ne comprenant tous les caract�res compris // entre <start> et <end> (inclus). String String::xrange(char start, char end) { // Par exemple - // xrange('a', 'j') retourne val = "abcdefghij" // xrange(1, 8) retourne val = "12345678" if (end < start) { cerr << "\nThe 'end' character is less than 'start' !!" << endl; return String(""); } // Note : 'end' est plus grand que 'start' ! Et ajoute +1 int tmpii = sizeof(char) * (end - start + 11); char *aa = (char *) malloc(tmpii); memset(aa, 0, tmpii); debug_("xrange tmpii", tmpii); for (int ii = start, jj = 0; ii <= end; ii++, jj++) { aa[jj] = ii; debug_("xrange aa[jj]", aa[jj] ); } String tmpstr(aa); free(aa); return tmpstr; } // Supprime tous les caract�res contenus dans <list>. Le caract�re par d�faut pour // <list> est l'espace ' '. String String::compress(char *list = " ") { // Par exemple - // compress("$,%") avec sval = "$1,934" retourne "1934" // compress() avec sval = "appelez moi alavoor vasudevan" returns "appelezmoialavoorvasudevan" int lenlist = strlen(list); register char *aa = strdup(sval); for (int ii = 0, jj = strlen(sval); ii < jj; ii++) // pour chaque caract�re de sval { for (int kk = 0; kk < lenlist; kk++) // pour chaque caract�re de "from" { if (aa[ii] == list[kk]) { strcpy(& aa[ii], & aa[ii+1]); } } } String tmpstr(aa); free(aa); return tmpstr; } // <newstr> est ins�r�e dans sval � partir de <start>. <newstr> est // compl�t�e ou tronqu�e � <length> caract�res. <length> est par d�faut la // longueur de la cha�ne <newstr> String String::insert(char *newstr, int start = 0, int lengthstr = 0, char padchar = ' ') { // Par exemple - // insert("quelquechose de nouveau", 8, 30, '*') avec sval = "vieille chose" // retourne "vieille quelquechose de nouveau*******chose" int tmplen = sizeof(char) * strlen(sval) + strlen(newstr) + lengthstr + 10; char *tmpaa = (char *) malloc (tmplen); memset(tmpaa, 0, tmplen); if (!start) // start == 0 { strcpy(tmpaa, newstr); strcat(tmpaa, this->sval); } else { strncpy(tmpaa, this->sval, start); strcat(tmpaa, newstr); strcat(tmpaa, & this->sval[start]); } String tmpstr(tmpaa); free(tmpaa); return tmpstr; } // Fonction insert surcharg�e String String::insert(int index, String str2, bool dummy) { *this = this->insert(str2.sval, index).sval; //debug_("tmpstr.sval", tmpstr.sval); return *this; } // Fonction insert surcharg�e String String::insert(int index, char ch, bool dummy) { char aa[2]; aa[0] = ch; aa[1] = 0; *this = this->insert(aa, index).sval; //debug_("tmpstr.sval", tmpstr.sval); return *this; } // Le r�sultat est une cha�ne de <length> caract�res compos�e des caract�res les plus � gauches de sval. // M�thode rapide pour justifier � gauche une cha�ne. String String::left(int slength = 0, char padchar = ' ') { // Par exemple - // left(15) avec sval = "Wig" retourne "Wig " // left(4) avec sval = "Wighat" retourne "Wigh" // left() avec sval = " Wighat" retourne "Wighat " if (!slength) // slength == 0 slength = strlen(sval); debug_("left() slength", slength); int tmpii = slength + 20; char *aa = (char *) malloc(tmpii); memset(aa, 0, tmpii); debug_("this->ltrim().sval ", this->ltrim().sval); strcpy(aa, this->ltrim().sval); debug_("left() aa", aa ); int currlen = strlen(aa); if (currlen < slength) { // pad the string now char ee[2]; ee[0] = padchar; ee[1] = 0; strcat(aa, this->repeat(ee, (unsigned int) (slength-currlen) ).sval); } else { aa[slength] = 0; } debug_("left() aa", aa ); String tmpstr(aa); free(aa); return tmpstr; } // Le r�sultat est une cha�ne de <length> caract�res compos�e des caract�res les plus � droite de sval. // M�thode rapide pour justifier � droite un cha�ne. String String::right(int slength = 0, char padchar = ' ') { // Par exemple - // right(10) avec sval = "never to saying " retourne " to saying" // right(4) avec sval = "Wighat" retourne "ghat" // right(8) avec sval = "4.50" retourne " 4.50" // right() avec sval = " 4.50 " retourne " 4.50" if (!slength) // slength == 0 slength = strlen(sval); debug_("right() slength", slength); int tmpii = slength + 20; char *aa = (char *) malloc(tmpii); memset(aa, 0, tmpii); int currlen = strlen(this->rtrim().sval); debug_("right() currlen", currlen ); if (currlen < slength) { // pad the string now char ee[2]; ee[0] = padchar; ee[1] = 0; strcpy(aa, this->repeat(ee, (unsigned int) (slength-currlen) ).sval); strcat(aa, this->rtrim().sval); debug_("right() aa", aa ); } else { strcpy(aa, this->rtrim().sval); strcpy(aa, & aa[currlen-slength]); aa[slength] = 0; } debug_("right() aa", aa ); String tmpstr(aa); free(aa); return tmpstr; } // <newstr> est superpos�e � sval en commen�ant � <start>. <newstr> est compl�t�e // ou tronqu�e � <length> caract�res. Par d�faut, la longueur <length> est la // longueur de la cha�ne newstr. String String::overlay(char *newstr, int start = 0, int slength = 0, char padchar = ' ') { // Par exemple - // overlay("12345678", 4, 10, '*') sur sval = "oldthing is very bad" // retourne "old12345678**ery bad" // overlay("12345678", 4, 5, '*') sur sval = "oldthing is very bad" // retourne "old12345ery bad" int len_newstr = strlen(newstr); if (!slength) // slength == 0 slength = len_newstr; char *aa = (char *) malloc(slength + len_newstr + 10); aa[0] = 0; char ee[2]; ee[0] = padchar; ee[1] = 0; if (len_newstr < slength) { // remplire maintenant strcpy(aa, newstr); strcat(aa, this->repeat(ee, (slength-len_newstr)).sval ); } else { strcpy(aa, newstr); aa[slength] = 0; } // Maintenant recouvrir la cha�ne String tmpstr(sval); debug_("tmpstr.sval", tmpstr.sval); for (int ii=start, jj=strlen(tmpstr.sval), kk=start+slength, mm=0; ii < jj; ii++, mm++) { if (ii == kk) break; if (mm == slength) break; tmpstr.sval[ii] = aa[mm]; } free(aa); debug_("tmpstr.sval", tmpstr.sval); return tmpstr; } // Si la cha�ne est litt�ralement �gale � ou non �gale � // Si type vaut false alors == bool String::_equalto(const String & rhs, bool type = false) { if (type == false) // test == { if (strlen(rhs.sval) == strlen(sval)) { if (!strncmp(rhs.sval, sval, strlen(sval))) // == 0 return true; else return false; } else return false; } else // test != { if (strlen(rhs.sval) != strlen(sval)) { if (!strncmp(rhs.sval, sval, strlen(sval))) // == 0 return true; else return false; } else return false; } } // Si la cha�ne est litt�ralement �gale � ou non �gale � // Si type vaut false alors == bool String::_equalto(const char *rhs, bool type = false) { if (type == false) // test == { if (strlen(rhs) == strlen(sval)) { if (!strncmp(rhs, sval, strlen(sval))) // == 0 return true; else return false; } else return false; } else // test != { if (strlen(rhs) != strlen(sval)) { if (!strncmp(rhs, sval, strlen(sval))) // == 0 return true; else return false; } else return false; } } // Fonction synonyme de vacuum() void String::clear() { sval = (char *) my_realloc(sval, 10); sval[0] = '\0'; } // Supprime tous les caract�res 'ch' en fin de cha�ne - voir aussi chop() // Par exemple : // sval = "abcdef\n\n\n" alors chopall() = "abcdef" // sval = "abcdefffff" alors chopall('f') = "abcde" void String::chopall(char ch='\n') { unsigned long tmpii = strlen(sval) - 1 ; for (; tmpii>= 0; tmpii--) { if (sval[tmpii] == ch) sval[tmpii] = 0; else break; } } // Supprime le caract�re de fin de la cha�ne - voir aussi chopall() // chop() est souvent utilis� pour supprimer le caract�re de fin de ligne void String::chop() { sval[strlen(sval)-1] = 0; } // Version surcharg�e de trim(). Modifie directement l'objet. void String::trim(bool dummy) { this->_trim(); } inline void String::_trim() { this->rtrim(true); this->ltrim(true); debug_("this->sval", this->sval); } // Version surcharg�e de ltrim(). Modifie directement l'objet. void String::ltrim(bool dummy) { this->_ltrim(); } inline void String::_ltrim() { // Peut causer des probl�mes dans my_realloc car // l'emplacement de bb peut �tre d�truit ! char *bb = sval; if (bb == NULL) return; while (isspace(*bb)) bb++; debug_("bb", bb); if (bb != NULL && bb != sval) { debug_("doing string copy", "done"); _str_cpy(bb); // cause des probl�mes dans my_realloc et bb va �tre d�truit ! } else debug_("Not doing string copy", "done"); } String String::ltrim() { String tmpstr(sval); tmpstr._ltrim(); return tmpstr; } // Version surcharg�e de rtrim(). Modifie directement l'objet. void String::rtrim(bool dummy) { this->_rtrim(); } inline void String::_rtrim() { for (long tmpii = strlen(sval) - 1 ; tmpii>= 0; tmpii--) { if ( isspace(sval[tmpii]) ) sval[tmpii] = '\0'; else break; } } String String::rtrim() { String tmpstr(sval); tmpstr._rtrim(); return tmpstr; } // Utilis� pour arrondir la partie frationnaire de r�els. // Arrondit les r�els avec la pr�cision souhait�e et stocke // le r�sultat dans le champ sval de la cha�ne. // Retourne aussi le r�sultat comme un char *. void String::roundf(float input_val, short precision) { float integ_flt, deci_flt; const short MAX_PREC = 4; debug_("In roundf", "ok"); if (precision> MAX_PREC) // pr�cision maximale support�e precision = MAX_PREC; // r�cup�re les parties enti�re et d�cimale du r�el deci_flt = modff(input_val, & integ_flt); for (int tmpzz = 0; tmpzz < precision; tmpzz++) { debug_("deci_flt", deci_flt); deci_flt *= 10; } debug_("deci_flt", deci_flt); unsigned long deci_int = (unsigned long) ( rint(deci_flt) ); sval = (char *) my_malloc(NUMBER_LENGTH); // float 70 chiffres max if (deci_int> 999) // (MAX_PREC) chiffres sprintf(sval, "%lu.%lu", (unsigned long) integ_flt, deci_int); else if (deci_int> 99) // (MAX_PREC - 1) chiffres sprintf(sval, "%lu.0%lu", (unsigned long) integ_flt, deci_int); else if (deci_int> 9) // (MAX_PREC - 2) chiffres sprintf(sval, "%lu.00%lu", (unsigned long) integ_flt, deci_int); else sprintf(sval, "%lu.00000%lu", (unsigned long) integ_flt, deci_int); } void String::roundd(double input_val, short precision) { double integ_flt, deci_flt; const short MAX_PREC = 6; if (precision> MAX_PREC) // pr�cision maximale support�e precision = MAX_PREC; debug_("In roundd", "ok"); // r�cup�re les parties enti�re et d�cimale du r�el deci_flt = modf(input_val, & integ_flt); for (int tmpzz = 0; tmpzz < precision; tmpzz++) { debug_("deci_flt", deci_flt); deci_flt *= 10; } debug_("deci_flt", deci_flt); sval = (char *) my_malloc(NUMBER_LENGTH); // double 70 chiffres max unsigned long deci_int = (unsigned long) ( rint(deci_flt) ); if (deci_int> 99999) // (MAX_PREC) chiffres sprintf(sval, "%lu.%lu", (unsigned long) integ_flt, deci_int); else if (deci_int> 9999) // (MAX_PREC - 1) chiffres sprintf(sval, "%lu.0%lu", (unsigned long) integ_flt, deci_int); else if (deci_int> 999) // (MAX_PREC - 2) chiffres sprintf(sval, "%lu.00%lu", (unsigned long) integ_flt, deci_int); else if (deci_int> 99) // (MAX_PREC - 3) chiffres sprintf(sval, "%lu.000%lu", (unsigned long) integ_flt, deci_int); else if (deci_int> 9) // (MAX_PREC - 4) chiffres sprintf(sval, "%lu.0000%lu", (unsigned long) integ_flt, deci_int); else // (MAX_PREC - 5) chiffres sprintf(sval, "%lu.00000%lu", (unsigned long) integ_flt, deci_int); } // Fournie seulement pour documenter // Vous devriez utiliser la fonction indexOf() bool String::contains(char *str2, int startIndex = 0) { // Par exemple - // if (indexOf("ohboy")> -1 ) // cout << "\nString contient 'ohboy'" << endl; // if (indexOf("ohboy") < 0 ) // cout << "\nString NE contient PAS 'ohboy'" << endl; // if (indexOf("ohboy", 4)> -1 ) // cout << "\nString contient 'ohboy'" << endl; // if (indexOf("ohboy", 4) < 0 ) // cout << "\nString NE contient PAS 'ohboy'" << endl; cerr << "\nYou must use indexOf() function instead of contains()\n" << endl; exit(-1); } // Fonction synonyme de empty() bool String::isNull() { if (sval[0] == '\0') return true; else { if (sval == NULL) return true; else return false; } } // Les caract�res blancs de d�but et de fin sont ignor�s. bool String::isInteger() { String tmpstr(sval); tmpstr.trim(true); debug_("tmpstr.sval", tmpstr.sval ); if ( strspn ( tmpstr.sval, "0123456789" ) != strlen(tmpstr.sval) ) return ( false ) ; else return ( true ) ; } // Fonction surcharg�e bool String::isInteger(int pos) { verifyIndex(pos); return (isdigit(sval[pos])); } // Les caract�res blancs de d�but et de fin sont ignor�s. bool String::isNumeric() { String tmpstr(sval); tmpstr.trim(true); debug_("tmpstr.sval", tmpstr.sval ); if ( strspn ( tmpstr.sval, "0123456789.+-e" ) != strlen(tmpstr.sval) ) return ( false ) ; else return ( true ) ; } // Fonction surcharg�e bool String::isNumeric(int pos) { verifyIndex(pos); return (isdigit(sval[pos])); } bool String::isEmpty() { if (strlen(sval) == 0) return true; else return false; } // Voir aussi explode() // Attention : l'objet String est modifi� et ne contient plus le token renvoy�. // Il est conseill� de sauvegarder la cha�ne originale avant d'appeler // cette fonction, comme par exemple ainsi : // String savestr = origstr; // String aa, bb, cc; // aa = origstr.token(); // bb = origstr.token(); // cc = origstr.token(); // // Cette m�thode retourne le premier token non s�parateur (par d�faut espace) de la cha�ne. String String::token(char seperator = ' ') { char ee[2]; ee[0] = seperator; ee[1] = 0; char *res = strtok(sval, ee); if (!res) // if res == NULL { debug_("token", res); debug_("sval", sval); return(String(sval)); } else { String tmpstr(res); // Utilise la longueur de la cha�ne sval et pas celle de res // car strtok() a mis un NULL ('\0') sur l'emplacement et // aussi car strtok() ignore les blancs initiaux de sval strcpy(sval, & sval[strlen(sval)+1]); debug_("token", res); debug_("sval", sval); return tmpstr; } } String String::crypt(char *original, char *salt) { return String(""); } int String::toInteger() { if ( strlen(sval) == 0 ) { cerr << "Cannot convert a zero length string " << " to a numeric" << endl ; abort() ; } if ( ! isInteger() ) { cerr << "Cannot convert string [" << sval << "] to an integer numeric string" << endl ; abort() ; } return ( atoi ( sval ) ) ; } long String::parseLong() { if ( strlen(sval) == 0 ) { cerr << "Cannot convert a zero length string " << " to a numeric" << endl ; abort() ; } if ( ! isInteger() ) { cerr << "Cannot convert string [" << sval << "] to an integer numeric string" << endl ; abort() ; } return ( atol ( sval ) ) ; } double String::toDouble() { if ( strlen(sval) == 0 ) { cerr << "Cannot convert a zero length string " << " to a numeric" << endl ; abort() ; } if ( ! isNumeric() ) { cerr << "Cannot convert string [" << sval << "] to a double numeric string" << endl ; abort() ; } double d = atof ( sval ) ; return ( d ) ; } String String::getline(FILE *infp = stdin) { register char ch, *aa = NULL; register const short SZ = 100; // Valeur initiale de ii> SZ donc aa est de la m�moire allou�e register int jj = 0; for (int ii = SZ+1; (ch = getc(infp)) != EOF; ii++, jj++) { if (ii> SZ) // alloue la memoire en paquets de SZ pour la performance { aa = (char *) realloc(aa, jj + ii + 15); // +15 par s�curit� ii = 0; } if (ch == '\n') // lit jusqu'� rencontrer une nouvelle ligne break; aa[jj] = ch; } aa[jj] = 0; _str_cpy(aa); // met la valeur dans la cha�ne free(aa); return *this; } /* void String::Format(const char *fmt, ... ) { va_list iterator; va_start(iterator, fmt ); va_end(iterator); } */ // contr�le qu'un indice se trouve dans les limites inline void String::verifyIndex(unsigned long index) const { if (index < 0 || index>= strlen(sval) ) { // throw "Index Out Of Bounds Exception"; cerr << "Index Out Of Bounds Exception at [" << index << "] in:\n" << sval << endl; exit(1); } } // contr�le qu'un indice se trouve dans les limites inline void String::verifyIndex(unsigned long index, char *aa) const { if (!aa) // aa == NULL { cerr << "\nverifyIndex(long, char *) str null value\n" << endl; exit(-1); } if (index < 0 || index>= strlen(aa) ) { cerr << "Index Out Of Bounds Exception at [" << index << "] in:\n" << aa << endl; exit(1); } } ////////////////////////////////////////////////////////// // Les fonctions priv�es commencent � partir d'ici... ////////////////////////////////////////////////////////// void String::_str_cpy(char bb[]) { debug_("In _str_cpy bb", bb); if (bb == NULL) { sval[0] = '\0'; return; } unsigned long tmpii = strlen(bb); if (tmpii == 0) { sval[0] = '\0'; return; } debug_("In _str_cpy tmpii", tmpii); debug_("In _str_cpy sval", sval); sval = (char *) my_realloc(sval, tmpii); //sval = new char [tmpii + SAFE_MEM_2]; debug_("In _str_cpy bb", bb); strncpy(sval, bb, tmpii); debug_("In _str_cpy sval", sval); sval[tmpii] = '\0'; debug_("In _str_cpy sval", sval); } void String::_str_cpy(int bb) { char tmpaa[100]; sprintf(tmpaa, "%d", bb); _str_cpy(tmpaa); } void String::_str_cpy(unsigned long bb) { char tmpaa[100]; sprintf(tmpaa, "%ld", bb); _str_cpy(tmpaa); } void String::_str_cpy(float bb) { char tmpaa[100]; sprintf(tmpaa, "%f", bb); _str_cpy(tmpaa); } void String::_str_cat(char bb[]) { unsigned long tmpjj = strlen(bb), tmpii = strlen(sval); sval = (char *) my_realloc(sval, tmpii + tmpjj); debug_("sval in _str_cat() ", sval); strncat(sval, bb, tmpjj); } void String::_str_cat(int bb) { char tmpaa[100]; sprintf(tmpaa, "%d", bb); unsigned long tmpjj = strlen(tmpaa), tmpii = strlen(sval); sval = (char *) my_realloc(sval, tmpii + tmpjj); strncat(sval, tmpaa, tmpjj); } void String::_str_cat(unsigned long bb) { char tmpaa[100]; sprintf(tmpaa, "%ld", bb); unsigned long tmpjj = strlen(tmpaa), tmpii = strlen(sval); sval = (char *) my_realloc(sval, tmpii + tmpjj); strncat(sval, tmpaa, tmpjj); } void String::_str_cat(float bb) { char tmpaa[100]; sprintf(tmpaa, "%f", bb); unsigned long tmpjj = strlen(tmpaa), tmpii = strlen(sval); sval = (char *) my_realloc(sval, tmpii + tmpjj); strncat(sval, tmpaa, tmpjj); } ////////////////////////////////////////////////////////// // Les op�rateurs sont d�finis � partir d'ici... ////////////////////////////////////////////////////////// String operator+ (const String & lhs, const String & rhs) { /*******************************************************/ // Note : pour concat�ner deux cha�nes, transtyper d'abord // en String comme ici : //aa = (String) "alkja " + " 99djd " ; /*******************************************************/ String tmp(lhs); tmp._str_cat(rhs.sval); return(tmp); /* if (String::_global_String == NULL) { String::_global_String = new String; String::_global_String->_str_cpy(lhs.sval); String::_global_String->_str_cat(rhs.sval); //return *String::_global_String; return String(String::_global_String->val); } */ /* else if (String::_global_String1 == NULL) { debug_("1)global", "ok" ); String::_global_String1 = new String; String::_global_String1->_str_cpy(lhs.sval); String::_global_String1->_str_cat(rhs.sval); return *String::_global_String1; } */ /* else { fprintf(stderr, "\nError: cannot alloc _global_String\n"); exit(-1); } */ /* String *aa = new String; aa->_str_cpy(lhs.sval); aa->_str_cat(rhs.sval); return *aa; */ } String String::operator+ (const String & rhs) { String tmp(*this); tmp._str_cat(rhs.sval); debug_("rhs.sval in operator+", rhs.sval ); debug_("tmp.sval in operator+", tmp.sval ); return (tmp); } // L'utilisation d'une r�f�rence acc�l�rera l'op�rateur = String& String:: operator= ( const String& rhs ) { if (& rhs == this) { debug_("Fatal Error: In operator(=). rhs is == to 'this pointer'!!", "ok" ); return *this; } this->_str_cpy(rhs.sval); debug_("rhs value", rhs.sval ); // Libere la memoire des variables globales //_free_glob(& String::_global_String); //if (String::_global_String == NULL) //fprintf(stderr, "\n_global_String is freed!\n"); //return (String(*this)); return *this; } // L'utilisation d'une r�f�rence acc�l�rera l'op�rateur = String& String::operator+= (const String & rhs) { /*******************************************************/ // Note : pour concat�ner deux cha�nes, transtyper d'abord // en String comme ici : //aa = (String) "cccc " + " dddd " ; /*******************************************************/ if (& rhs == this) { debug_("Fatal error: In operator+= rhs is equals 'this' ptr", "ok"); return *this; } this->_str_cat(rhs.sval); return *this; //return (String(*this)); } bool String::operator== (const String & rhs) { return(_equalto(rhs.sval)); } bool String::operator== (const char *rhs) { return(_equalto(rhs)); } bool String::operator!= (const String & rhs) { return(_equalto(rhs.sval, true)); } bool String::operator!= (const char *rhs) { return(_equalto(rhs, true)); } char String::operator[] (unsigned long Index) const { verifyIndex(Index); return sval[Index]; } char & String::operator[] (unsigned long Index) { verifyIndex(Index); return sval[Index]; } istream & operator>> (istream & In, String & str2) { // alloue la taille max de 2048 caract�res static char aa[MAX_ISTREAM_SIZE]; In>> aa; str2 = aa; // affecte aa � la r�f�rence return In; // retourne un istream } ostream & operator << (ostream & Out, const String & str2) { Out << str2.sval; return Out; } //////////////////////////////////////////////////// // Imite StringBuffer Object // M�Thodes de StringBuffer //////////////////////////////////////////////////// // Imite StringBuffer ; le constructeur par d�faut // (celui sans param�tre) r�serve de la place pour 16 // caract�res. StringBuffer::StringBuffer() :String() // appelle le constructeur de la classe de base sans param�tres { debug_("in StringBuffer cstr()", "ok"); } // Imite StringBuffer StringBuffer::StringBuffer(int size) :String(size, true) // appelle le constructeur de la classe de base sans param�tres { // String(size, true) -- ne pas l'appeler ici dans le corps de la // fonction mais durant la phase d'initialisation pour �viter un // appel suppl�mentaire du constructeur par d�faut de la classe de // base et �tre plus rapide et plus efficace debug_("in StringBuffer cstr(int size)", "ok"); } // Imite StringBuffer // appelle le constructeur de la classe de base avec une cha�ne en param�tre StringBuffer::StringBuffer(String str) :String(str.val()) // appelle le constructeur de la classe de base { // String(str.val()) -- ne pas l'appeler ici dans le corps de la // fonction mais durant la phase d'initialisation pour �viter un // appel suppl�mentaire du constructeur par d�faut de la classe de // base et �tre plus rapide et plus efficace debug_("in StringBuffer cstr(String str)", "ok"); } // Imite StringBuffer StringBuffer::~StringBuffer() { debug_("in StringBuffer dstr()", "ok"); } // Imite la classe Float // appelle le constructeur de la classe de base avec une cha�ne en param�tre Float::Float(String str) :String(str.val()) // appelle le constructeur de la classe de base { // String(str.val()) -- ne pas l'appeler ici dans le corps de la // fonction mais durant la phase d'initialisation pour �viter un // appel suppl�mentaire du constructeur par d�faut de la classe de // base et �tre plus rapide et plus efficace debug_("in Float cstr(String str)", "ok"); } // Imite la classe Double // appelle le constructeur de la classe de base avec une cha�ne en param�tre Double::Double(String str) :String(str.val()) // appelle le constructeur de la classe de base { // String(str.val()) -- ne pas l'appeler ici dans le corps de la // fonction mais durant la phase d'initialisation pour �viter un // appel suppl�mentaire du constructeur par d�faut de la classe de // base et �tre plus rapide et plus efficace debug_("in Double cstr(String str)", "ok"); } // Imite la classe StringReader // appelle le constructeur de la classe de base avec une cha�ne en param�tre StringReader::StringReader(String str) :String(str.val()) // appelle le constructeur de la classe de base { // String(str.val()) -- ne pas l'appeler ici dans le corps de la // fonction mais durant la phase d'initialisation pour �viter un // appel suppl�mentaire du constructeur par d�faut de la classe de // base et �tre plus rapide et plus efficace debug_("in StringReader cstr(String str)", "ok"); _curpos = 0; _mark_pos = 0; } // Imite la m�thode read de la classe StringReader int StringReader::read() { _curpos++; if (_curpos> strlen(sval) ) return -1; return sval[_curpos-1]; } // Lit des caract�res dans une portion d'un tableau // cbuf est le tampon destination, offset est le d�calage indiquant o� �crire // les caract�res, length est le nombre maximum de caract�res � lire // Retourne le nombre de caract�res lus ou -1 en cas de fin du flux int StringReader::read(char cbuf[], int offset, int length) { if (_curpos> strlen(sval) - 1 ) return -1; strncpy(& cbuf[offset], & sval[_curpos], length); _curpos += length; return length; } // Marque la position courante dans le flux. Les appels suivants // � reset() repositionneront le flux � ce point. // Le param�tre 'readAheadLimit' limite le nombre de caract�res qui // pourraient �tre lus tout en pr�servant la marque. // Comme le flux d'entr�e provient d'une cha�ne, il n'y a pas de //limite actuellement, donc l'argument est ignor�. void StringReader::mark(int readAheadLimit) { _mark_pos = _curpos; } // r�initialise le flux � la marque la plus r�cente, ou au d�but de // la cha�ne si aucun marque n'a �t� pos�e void StringReader::reset() { _curpos = _mark_pos; } // Passe des caract�res. Cette m�thode bloquera jusqu'a ce que des caract�res soient // disponibles, qu'une erreur arrive ou que la fin du flux soit atteinte. // Param�tre ii : nombre de caract�res � passer // Retourne : le nombre courant de caract�res pass�s long StringReader::skip(long ii) { long tmpjj = strlen(sval) - _curpos - 1; if (ii> tmpjj) ii = tmpjj; _curpos = ii; return ii; } // Imite la classe StringWriter StringWriter::StringWriter() { debug_("in StringWriter cstr()", "ok"); char *aa = (char *) malloc(300); memset(aa, ' ', 299); // remplit avec des blancs aa[300] = 0; String((char *) aa); my_free(aa); } StringWriter::StringWriter(int bufferSize) { debug_("in StringWriter cstr(int bufferSize)", "ok"); char *aa = (char *) malloc(bufferSize); memset(aa, ' ', bufferSize-1); // remplit avec des blancs aa[bufferSize] = 0; String((char *) aa); my_free(aa); } void StringWriter::write(int bb) { _str_cat(bb); } void StringWriter::write(char *bb) { _str_cat(bb); } void StringWriter::write(String bb) { _str_cat(bb.val()); } void StringWriter::write(char *bb, int startIndex, int endIndex) { char *aa = strdup(bb); // teste le null dans verifyIndex verifyIndex(startIndex, aa); verifyIndex(endIndex, aa); aa[endIndex] = 0; _str_cat(& aa[startIndex]); } void StringWriter::write(String str, int startIndex, int endIndex) { write(str.val(), startIndex, endIndex); }
Hosting by: Hurra Communications GmbH
Generated: 2007-01-26 18:01:30