// __PRETTY_FUNCTION__ // http://www.icce.rug.nl/documents/cplusplus/cplusplus02.html#l13 #ifndef DSTRING_H #define DSTRING_H #include #include #include #include #include #include // #include using namespace std; // #define String string // Default array increment (uses here a number divisible by 4) #define DSTRING_INCR 4 // Tolerable waste of space #define DSTRING_MAX_WASTE (3 * DSTRING_INCR - 1) class dstring { private: unsigned int len; char *txt; public: // Maximum (iostream) input string length enum {STR_MAXLEN = 2048}; dstring(); String(const String &_str); String(const char *_txt); String(char _ch, unsigned int _count); String(const char _c); String(const int _i); String(const unsigned int _i); ~String(); String &operator = (const String &_str); friend String operator + (const String &_str1, const String &_str2); friend String operator + (const String &_str1, const char _ch); friend String operator + (const String &_str1, const char *_cstr); // friend String operator + (const String &_str1, unsigned int _int); String &operator += (const String &_str); String &operator += (char _ch); int operator == (const String &_str); int operator != (const String &_str); int operator > (const String &_str); int operator >= (const String &_str); int operator < (const String &_str); int operator <= (const String &_str); char &at(unsigned int _pos); char &operator [] (unsigned int _pos); friend ostream &operator << (ostream &_out, const String &_str); friend istream &operator >> (istream &_in, String &_str); friend istream &getline(istream &_in, String &_str); friend fstream & operator >> (fstream &_in, String &_str); friend fstream & getline(fstream &_in, String &_str); String substr(unsigned int _fromPos, unsigned int _numChar); String left (const unsigned _numChar); String right(const unsigned _numChar); String resize(unsigned _len); String trim(); String ltrim(); String rtrim(); void toupper(); void tolower(); String asupper(); String aslower(); void align(unsigned _len, char _alignment, char _alignChar, int _cut); int isInteger(); int isReal(); int isNumeric(); int asInteger(unsigned remove_spaces = true); double asNumber(unsigned remove_spaces = true); inline unsigned int length() const { return len; }; inline operator const char *() const { return (const char *)txt; }; inline int isNull() { return (!len); }; private: void deleteTxt(); void allocateTxt(unsigned int _size); int s_stricmp(char *_s1, char *_s2); char *s_toupper(char *_txt); char *s_tolower(char *_txt); }; void String::deleteTxt() { if (len) delete [] txt; txt = NULL; len = 0; }; void String::allocateTxt(unsigned int _length) { len = _length; try { txt = new char[len+1]; if (!txt) throw "allocateTxt: Cannot allocate memory"; *txt = '\0'; } catch ( char *e) { cerr << e << endl; throw; } /* unsigned int siz; try { // Expand? if (_length > alloc_len) { char *p; // Calculate new size siz = (((_length - 1) / DSTRING_INCR)* DSTRING_INCR) + DSTRING_INCR; // for '\0' siz += 1; p = new char[siz * sizeof(char)]; // Enough memory? if (!p) throw "allocateTxt: Cannot allocate memory"; memmove(p, txt, len*sizeof(char)); if (txt) delete [] txt; txt = p; // Set new slots to NULL memset(txt + len, '\0', (siz - len)*sizeof(char)); alloc_len = siz; } } catch ( char *e) { cerr << e << endl; throw; } */ } String::String() { this->allocateTxt(0); }; String::String(const String &_str) { this->allocateTxt(_str.len); strcpy(txt, _str); }; String::String(const char _ch, const unsigned int _count) { // A, 3: 012345 // AAA unsigned int i; this->allocateTxt(_count); for (i=0;i<_count;i++) { txt[i] = _ch; } txt[len] = '\0'; }; String::String(const char *_txt) { this->allocateTxt(strlen(_txt)); strcpy(txt, _txt); }; String::String(const int _i) { // Integer --> String char s[30]; sprintf(s, "%d", _i); // itoa(_i, s, 10); this->allocateTxt(strlen(s)); strcpy(txt, s); }; String::String(const unsigned int _i) { // Integer --> String char s[30]; sprintf(s, "%d", _i); // itoa(_i, s, 10); this->allocateTxt(strlen(s)); strcpy(txt, s); }; String::String(const char _c) { // char --> String(1) char s[2]; s[0] = _c; s[1] = '\0'; this->allocateTxt(strlen(s)); strcpy(txt, s); }; String::~String() { this->deleteTxt(); }; String &String::operator = (const String &_str) { // Asignment (=) operator this->deleteTxt(); this->allocateTxt(_str.len); strcpy(txt, _str); return *this; } String operator + (const String &_str1, const String &_str2) { String tempStr; tempStr.len = _str1.length() + _str2.length(); if (!tempStr.len) return tempStr; tempStr.txt = new char[tempStr.len+1]; strcpy(tempStr.txt, _str1); strcpy(tempStr.txt + _str1.length(), _str2); tempStr.txt[tempStr.len] = '\0'; return tempStr; } String operator + (const String &_str, const char *_cstr) { String tempStr; tempStr.len = _str.length() + strlen(_cstr); if (!tempStr.len) return tempStr; tempStr.txt = new char[tempStr.len+1]; strcpy(tempStr.txt, _str); strcpy(tempStr.txt + _str.len, _cstr); tempStr.txt[tempStr.len] = '\0'; return tempStr; } String operator + (const String &_str, const char _ch) { String tempStr; tempStr.len = _str.length() + 1; tempStr.txt = new char[tempStr.len+1]; strcpy(tempStr.txt, _str); tempStr.txt[tempStr.len-1] = _ch; tempStr.txt[tempStr.len] = '\0'; return tempStr; } /* String operator + (const String &_str, const int _int) { String tempStr; char s[30]; itoa(_int, s, 10); tempStr = _str + s; return tempStr; } */ inline String &String::operator += (const String &_str) { *this = *this + _str; return *this; } inline String &String::operator += (const char _ch) { *this = *this + _ch; return *this; } char &String::at(unsigned int _pos) { return txt[_pos]; } char &String::operator [] (unsigned int _pos) { String tempStr = ""; if (_pos < len) return txt[_pos]; else return tempStr.at(0); } inline int String::operator == (const String &_str) { // Case insensitive return s_stricmp(txt, _str.txt) == 0; } inline int String::operator != (const String &_str) { // Case insensitive return s_stricmp(txt, _str.txt) != 0; } inline int String::operator > (const String &_str) { // Case insensitive return s_stricmp(txt, _str.txt) > 0; } inline int String::operator >= (const String &_str) { // Case insensitive return s_stricmp(txt, _str.txt) > 0; } inline int String::operator < (const String &_str) { // Case insensitive return s_stricmp(txt, _str.txt) < 0; } inline int String::operator <= (const String &_str) { // Case insensitive return s_stricmp(txt, _str.txt) <= 0; } ostream & operator<<( ostream & out, const String &_str) { return out << (const char*)_str; } istream & operator>>(istream & _in, String &_str) { char cbuf[String::STR_MAXLEN]; _in >> cbuf; _str = cbuf; return _in; } istream & getline(istream &_in, String & _str) { char cbuf[String::STR_MAXLEN]; _in.getline(cbuf, String::STR_MAXLEN); _str = cbuf; return _in; } fstream & operator>>(fstream & _in, String &_str) { char cbuf[String::STR_MAXLEN]; _in.width(String::STR_MAXLEN); _in >> cbuf; _str = cbuf; return _in; } fstream & getline(fstream &_in, String & _str) { char cbuf[String::STR_MAXLEN]; _in.getline(cbuf, String::STR_MAXLEN); _str = cbuf; return _in; } String String::substr(const unsigned _fromPos, const unsigned _numChar) { // Return sub string. 0-based String tempStr; char cbuf[String::STR_MAXLEN]; unsigned i, j = 0; for (i=_fromPos; (j<_numChar && i=0 && toPos >= 0; i--) { if (txt[i] != ' ' && txt[i] != '\t') break; toPos--; }; return this->substr(fromPos, toPos - fromPos + 1); }; String String::ltrim() { unsigned fromPos = 0; unsigned i; for (i=0; isubstr(fromPos, len); }; String String::rtrim() { unsigned toPos = len-1; int i; for (i=len-1; i>=0; i--) { if (txt[i] != ' ' && txt[i] != '\t') break; toPos--; }; return this->substr(0, toPos+1); }; int String::isInteger() { unsigned i; for (i=0; i 0 && !exponential && (strchr("eE", txt[i]))) { exponential = true; continue; } else if (exponential && !exponential_sign && strchr("eE", txt[i-1]) && strchr("+-", txt[i])) { exponential_sign = true; continue; } else if (strchr("0123456789", txt[i])) { continue; } else { return (false); } } return (true); }; int String::isNumeric() { return this->isReal(); }; int String::asInteger(unsigned remove_spaces) { if (remove_spaces) { String tempStr = this->trim(); return atoi(tempStr); } else return atoi(*this); }; double String::asNumber(unsigned remove_spaces) { if (remove_spaces) { String tempStr = this->trim(); return atof(tempStr); } else return atof(*this); }; void String::toupper() { if (txt) s_toupper(txt); }; void String::tolower() { if (txt) s_tolower(txt); }; String String::asupper() { String temp; unsigned i; for (i=0; i