You can download all programs as a single tar.gz file from Download mychar . To get this file, in the web-browser, save this file as 'Text' type.
//***************************************************************** // Copyright policy is GNU/GPL but additional restriction is // that you include author's name and email on all copies // Author : Al Dev Email: alavoor@yahoo.com //***************************************************************** // Use string class or this class // // To prevent memory leaks - a char class to manage character variables // Always prefer to use string class // instead of char[] or char * // // To compile and test this program do - // g++ mychar.cpp #include "mychar.h" // Global variables .... //mychar *mychar::global_mychar = NULL; // global var list<mychar> mychar::explodeH; mychar::mychar() { debug_("In cstr()", "ok"); val = (char *) my_malloc(sizeof(char)* INITIAL_SIZE); } mychar::mychar(char *bb) { unsigned long tmpii = strlen(bb); val = (char *) my_malloc(sizeof(char)* tmpii); strncpy(val, bb, tmpii); val[tmpii] = '\0'; //debug_("In cstr(char *bb) bb", bb); //debug_("In cstr(char *bb) val", val); #ifdef DEBUG //fprintf(stderr, "\nAddress of val=%x\n", & val); //fprintf(stderr, "\nAddress of this-pointer=%x\n", this); #endif // DEBUG } mychar::mychar(int bb) { val = (char *) my_malloc(NUMBER_LENGTH); // integers 70 digits max sprintf(val, "%d", bb); } mychar::mychar(unsigned long bb) { val = (char *) my_malloc(NUMBER_LENGTH); // long 70 digits max sprintf(val, "%lu", bb); } mychar::mychar(float bb) { val = (char *) my_malloc(NUMBER_LENGTH); // float 70 digits max sprintf(val, "%f", bb); } mychar::mychar(double bb) { val = (char *) my_malloc(NUMBER_LENGTH); // double 70 digits max sprintf(val, "%f", bb); } // Copy Constructor needed by operator + mychar::mychar(const mychar & rhs) { // Do a deep-copy instead of compiler's default shallow copy copy-cstr debug_("In copy-cstr()", "ok"); unsigned long tmpii = strlen(rhs.val); val = (char *) my_malloc(sizeof(char)* tmpii); strncpy(val, rhs.val, tmpii); val[tmpii] = '\0'; } mychar::~mychar() { //debug_("In dstr val", val); #ifdef DEBUG //fprintf(stderr, "\nAddress of val=%x\n", & val); //fprintf(stderr, "\nAddress of this-pointer=%x\n", this); #endif // DEBUG my_free(val); //delete [] val; val = NULL; } // MUST use pointer-to-pointer **aa, otherwise the argument // is NOT freed !! /* inline void mychar::free_glob(mychar **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"); } */ // Explodes the string and returns the list in // the list-head pointer explodeH void mychar::explode(char *seperator) { char *aa = NULL, *bb = NULL; aa = (char *) my_malloc(length()); for (bb = strtok(aa, seperator); bb != NULL; bb = strtok(NULL, seperator) ) { mychar *tmp = new mychar(bb); mychar::explodeH.insert(mychar::explodeH.end(), *tmp); } my_free(aa); list<mychar>::iterator iter1; // see file include/g++/stl_list.h debug_("Before checking explode..", "ok"); if (mychar::explodeH.empty() == true ) { debug_("List is empty!!", "ok"); } for (iter1 = mychar::explodeH.begin(); iter1 != mychar::explodeH.end(); iter1++) { if (iter1 == NULL) { debug_("Iterator iter1 is NULL!!", "ok" ); break; } debug_("(*iter1).val", (*iter1).val); } } // Implodes the strings in the list-head // pointer explodeH and returns the mychar class void mychar::implode(char *glue) { } // Joins the strings in the list-head // pointer explodeH and returns the mychar class void mychar::join(char *glue) { implode(glue); } // Repeat the input string n times void mychar::repeat(char *input, unsigned int multiplier) { // For example - // repeat("1", 4) returns "1111" if (!input) // input == NULL { val[0] = 0; return; } val = (char *) my_malloc(strlen(input) * multiplier); for (unsigned int tmpii = 0; tmpii < multiplier; tmpii++) { strcat(val, input); } } // Reverse the string void mychar::reverse() { // For example - // reverse() on "12345" returns "54321" char aa; unsigned long tot_len = length(); unsigned long midpoint = tot_len / 2; for (unsigned long tmpjj = 0; tmpjj < midpoint; tmpjj++) { aa = val[tmpjj]; // temporary storage var val[tmpjj] = val[tot_len - tmpjj - 1]; // swap the values val[tot_len - tmpjj - 1] = aa; // swap the values } } // Replace all occurences of string 'needle' with 'str' in the haystack 'val' void mychar::replace(char *needle, char *str) { // For example - // replace("AAA", "BB") on val = "some AAA and AAACC" // reurns val = "some BB and BBCC" } // Translate certain chars void mychar::str_tr(char *from, char *to) { // For e.g ("abcd", "ABC") translates all occurences of each // character in 'from' to corresponding character in 'to' } // Center the text void center(int length, char padchar = ' ') { // For example - // center(10, '*') on val="aa" returns "****aa****" // center(10) on val="aa" returns " aa " // The result is a string of 'length' characters with val centered in it. } // Formats the original string by placing <number> of <padchar> characters // between each set of blank-delimited words. Leading and Trailing blanks // are always removed. If <number> is omitted or is 0, then all spaces are // in the string are removed. The default number is 0 and // default padchar ' ' void space(int number, char padchar = ' ') { // For example - // space(3) on val = "I do not know" // will return "I do not know" // space(1, '_') on val = "A deep black space" // will return "A_deep_black_space" // space() on val = "I know this" // will return "Iknowthis" } // The result is string comprised of all characters between // and including <start> and <end> void xrange(char start, char end) { // For example - // xrange('a', 'j') returns val = "abcdefghij" // xrange(1, 8) returns val = "12345678" } // Removes any characters contained in <list>. The default character // for <list> is a blank ' ' void compress(char *list) { // For example - // compress("$,%") on val = "$1,934" returns "1934" // compress() on val = "call me alavoor vasudevan" returns "callmealavoorvasudevan" } // Deletes a portion of string of <length> characters from <start> position. // If start is greater than the string length then string is unchanged. void delstr(int start, int length) { // For example - // delstr(3,3) on val = 'pokemon' returns 'poon' } // The <newstr> in inserted into val beginning at <start>. The <newstr> will // be padded or truncated to <length> characters. The default <length> is // string length of newstr void insert(char *newstr, int start = 0, int length = 0, char padchar = ' ') { // For example - // insert("something new", 4, 20, '*') on val = "old thing" // returns "old something new*******thing" } // The result is string of <length> chars madeup of leftmost chars in val. // Quick way to left justify a string. void left(int length = 0, char padchar = ' ') { // For example - // left(10) on val = "Wig" returns "Wig " // left(4) on val = "Wighat" returns "Wigh" } // The result is string of <length> chars madeup of rightmost chars in val. // Quick way to right justify a string. void right(int length = 0, char padchar = ' ') { // For example - // right(10) on val = "never stop to saying" returns " to saying" // right(4) on val = "Wighat" returns "ghat" // right(6) on val = "4.50" returns " 4.50" } // The <newstr> in overlayed into val beginning at <start>. The <newstr> will // be padded or truncated to <length> characters. The default <length> is // string length of newstr void overlay(char *newstr, int start = 0, int length = 0, char padchar = ' ') { // For example - // overlay("12345678", 4, 10, '*') on val = "oldthing is very bad" // returns "old12345678**ery bad" } // sub string mychar mychar::substr(int start, int length = 0) { if (!length) // length == 0 return(mychar(& val[start-1]) ); else { mychar tmp = mychar(& val[start-1]); tmp.val[length-1] = 0; return(tmp); } } // If string is literrally equal to .. or not equal to // If type is false then it is == bool mychar::equalto(const mychar & rhs, bool type = false) { if (type == false) // test for == { if (strlen(rhs.val) == length()) { if (!strncmp(rhs.val, val, length())) // == 0 return true; else return false; } else return false; } else // test for != { if (strlen(rhs.val) != length()) { if (!strncmp(rhs.val, val, length())) // == 0 return true; else return false; } else return false; } } // If string is literrally equal to .. or not equal to // If type is false then it is == bool mychar::equalto(const char *rhs, bool type = false) { if (type == false) // test for == { if (strlen(rhs) == length()) { if (!strncmp(rhs, val, length())) // == 0 return true; else return false; } else return false; } else // test for != { if (strlen(rhs) != length()) { if (!strncmp(rhs, val, length())) // == 0 return true; else return false; } else return false; } } // find position, matching substr beginning from start.. long mychar::pos(char *substr, unsigned long start) { char * tok; long res = -1; if ( !isnull() && (start < strlen(val) ) ) { tok = strstr(val + start, substr); if (tok == NULL) res = -1; else res = (long) (tok - val); } return res; } bool mychar::isnull() { if (val[0] == '\0') return true; else { if (val == NULL) return true; else return false; } } void mychar::clear() { val = (char *) my_realloc(val, 10); val[0] = '\0'; } // Remove trailing new-lines void mychar::chop() { unsigned long tmpii = strlen(val) - 1 ; for (; tmpii >= 0; tmpii--) { if (val[tmpii] == '\n') val[tmpii] = 0; else break; } } void mychar::ltrim() { // May cause problems in my_realloc since // location of bb will be destroyed !! char *bb = val; if (bb == NULL) return; while (isspace(*bb)) bb++; debug_("bb", bb); if (bb != NULL && bb != val) { debug_("doing string copy", "done"); //str_cpy(bb); // causes problems in my_realloc and bb is getting destroyed!! strcpy(val, bb); // strcpy is ok since val space is > bb space } else debug_("Not doing string copy", "done"); } void mychar::rtrim() { for (long tmpii = strlen(val) - 1 ; tmpii >= 0; tmpii--) { if ( isspace(val[tmpii]) ) val[tmpii] = '\0'; else break; } } void mychar::trim() { rtrim(); ltrim(); } void mychar::to_lower() { for (long tmpii = strlen(val); tmpii >= 0; tmpii--) { val[tmpii] = tolower(val[tmpii]); } } // Use for rounding off fractions digits of floats // Rounds-off floats with given precision and then // stores the result into mychar's val field // Also returns the result as a char * void mychar::roundf(float input_val, short precision) { float integ_flt, deci_flt; const short MAX_PREC = 4; debug_("In roundf", "ok"); if (precision > MAX_PREC) // this is the max reliable precision precision = MAX_PREC; // get the integral and decimal parts of the float value.. 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) ); val = (char *) my_malloc(NUMBER_LENGTH); // float 70 digits max if (deci_int > 999) // (MAX_PREC) digits sprintf(val, "%lu.%lu", (unsigned long) integ_flt, deci_int); else if (deci_int > 99) // (MAX_PREC - 1) digits sprintf(val, "%lu.0%lu", (unsigned long) integ_flt, deci_int); else if (deci_int > 9) // (MAX_PREC - 2) digits sprintf(val, "%lu.00%lu", (unsigned long) integ_flt, deci_int); else sprintf(val, "%lu.00000%lu", (unsigned long) integ_flt, deci_int); } void mychar::roundd(double input_val, short precision) { double integ_flt, deci_flt; const short MAX_PREC = 6; if (precision > MAX_PREC) // this is the max reliable precision precision = MAX_PREC; debug_("In roundd", "ok"); // get the integral and decimal parts of the double value.. 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); val = (char *) my_malloc(NUMBER_LENGTH); // double 70 digits max unsigned long deci_int = (unsigned long) ( rint(deci_flt) ); if (deci_int > 99999) // (MAX_PREC) digits sprintf(val, "%lu.%lu", (unsigned long) integ_flt, deci_int); else if (deci_int > 9999) // (MAX_PREC - 1) digits sprintf(val, "%lu.0%lu", (unsigned long) integ_flt, deci_int); else if (deci_int > 999) // (MAX_PREC - 2) digits sprintf(val, "%lu.00%lu", (unsigned long) integ_flt, deci_int); else if (deci_int > 99) // (MAX_PREC - 3) digits sprintf(val, "%lu.000%lu", (unsigned long) integ_flt, deci_int); else if (deci_int > 9) // (MAX_PREC - 4) digits sprintf(val, "%lu.0000%lu", (unsigned long) integ_flt, deci_int); else // (MAX_PREC - 5) digits sprintf(val, "%lu.00000%lu", (unsigned long) integ_flt, deci_int); } void mychar::to_upper() { for (long tmpii = strlen(val); tmpii >= 0; tmpii--) { val[tmpii] = toupper(val[tmpii]); } } void mychar::str_cpy(char bb[]) { debug_("In str_cpy bb", bb); if (bb == NULL) { val[0] = '\0'; return; } unsigned long tmpii = strlen(bb); if (tmpii == 0) { val[0] = '\0'; return; } debug_("In str_cpy tmpii", tmpii); debug_("In str_cpy val", val); val = (char *) my_realloc(val, tmpii); //val = new char [tmpii + SAFE_MEM_2]; debug_("In str_cpy bb", bb); strncpy(val, bb, tmpii); debug_("In str_cpy val", val); val[tmpii] = '\0'; debug_("In str_cpy val", val); } void mychar::str_cpy(int bb) { char tmpaa[100]; sprintf(tmpaa, "%d", bb); str_cpy(tmpaa); } void mychar::str_cpy(unsigned long bb) { char tmpaa[100]; sprintf(tmpaa, "%ld", bb); str_cpy(tmpaa); } void mychar::str_cpy(float bb) { char tmpaa[100]; sprintf(tmpaa, "%f", bb); str_cpy(tmpaa); } void mychar::str_cat(char bb[]) { unsigned long tmpjj = strlen(bb), tmpii = strlen(val); val = (char *) my_realloc(val, tmpii + tmpjj); debug_("val in str_cat() ", val); strncat(val, bb, tmpjj); } void mychar::str_cat(int bb) { char tmpaa[100]; sprintf(tmpaa, "%d", bb); unsigned long tmpjj = strlen(tmpaa), tmpii = strlen(val); val = (char *) my_realloc(val, tmpii + tmpjj); strncat(val, tmpaa, tmpjj); } void mychar::str_cat(unsigned long bb) { char tmpaa[100]; sprintf(tmpaa, "%ld", bb); unsigned long tmpjj = strlen(tmpaa), tmpii = strlen(val); val = (char *) my_realloc(val, tmpii + tmpjj); strncat(val, tmpaa, tmpjj); } void mychar::str_cat(float bb) { char tmpaa[100]; sprintf(tmpaa, "%f", bb); unsigned long tmpjj = strlen(tmpaa), tmpii = strlen(val); val = (char *) my_realloc(val, tmpii + tmpjj); strncat(val, tmpaa, tmpjj); } mychar operator+ (const mychar & lhs, const mychar & rhs) { /*******************************************************/ // Note : For adding two char strings, first cast mychar // as in - //aa = (mychar) "alkja " + " 99djd " ; /*******************************************************/ mychar tmp(lhs); tmp.str_cat(rhs.val); return(tmp); /* if (mychar::global_mychar == NULL) { mychar::global_mychar = new mychar; mychar::global_mychar->str_cpy(lhs.val); mychar::global_mychar->str_cat(rhs.val); //return *mychar::global_mychar; return mychar(mychar::global_mychar->val); } */ /* else if (mychar::global_mychar1 == NULL) { debug_("1)global", "ok" ); mychar::global_mychar1 = new mychar; mychar::global_mychar1->str_cpy(lhs.val); mychar::global_mychar1->str_cat(rhs.val); return *mychar::global_mychar1; } */ /* else { fprintf(stderr, "\nError: cannot alloc global_mychar\n"); exit(-1); } */ /* mychar *aa = new mychar; aa->str_cpy(lhs.val); aa->str_cat(rhs.val); return *aa; */ } mychar mychar::operator+ (const mychar & rhs) { mychar tmp(*this); tmp.str_cat(rhs.val); debug_("rhs.val in operator+", rhs.val ); debug_("tmp.val in operator+", tmp.val ); return (tmp); } // Using reference will be faster in = operator mychar& mychar:: operator= ( const mychar& rhs ) { if (& rhs == this) { debug_("Fatal Error: In operator(=). rhs is == to 'this pointer'!!", "ok" ); return *this; } this->str_cpy(rhs.val); debug_("rhs value", rhs.val ); // Free global vars memory //free_glob(& mychar::global_mychar); //if (mychar::global_mychar == NULL) //fprintf(stderr, "\nglobal_mychar is freed!\n"); //return (mychar(*this)); return *this; } // Using reference will be faster in = operator mychar& mychar::operator+= (const mychar & rhs) { /*******************************************************/ // Note : For adding two char strings, first cast mychar // as in - //aa += (mychar) "cccc" + "dddd"; /*******************************************************/ if (& rhs == this) { debug_("Fatal error: In operator+= rhs is equals 'this' ptr", "ok"); return *this; } this->str_cat(rhs.val); return *this; //return (mychar(*this)); } bool mychar::operator== (const mychar & rhs) { return(equalto(rhs.val)); } bool mychar::operator== (const char *rhs) { return(equalto(rhs)); } bool mychar::operator!= (const mychar & rhs) { return(equalto(rhs.val, true)); } bool mychar::operator!= (const char *rhs) { return(equalto(rhs, true)); }