home *** CD-ROM | disk | FTP | other *** search
- /* -------------------------------------------------------------------- */
- /* String++ Version 2.10 str.cpp Last revised 10/08/92 */
- /* */
- /* Enhanced string class for Turbo C++/Borland C++. */
- /* Copyright 1991, 1992 by Carl W. Moreland */
- /* -------------------------------------------------------------------- */
-
- #include <ctype.h>
- #include <stdlib.h>
- #include "str.h"
-
- /* ----- Constructors/Destructors ------------------------------------- */
-
- string::string()
- {
- _ptr = new char[1]; // NULL string
- _ptr[0] = '\0';
- }
-
- string::string(const char c, unsigned n)
- {
- _ptr = new char[n+1]; // allocate memory for n chars
-
- for(int i=0; i<n; i++)
- _ptr[i] = c; // copy n chars
- _ptr[i] = '\0'; // NULL terminate
- }
-
- string::string(const char *s, unsigned pos, unsigned len)
- {
- int s_len = strlen(s);
-
- if(pos > s_len)
- pos = s_len;
- if(len > s_len - pos)
- len = s_len - pos;
-
- _ptr = new char[len+1]; // allocate new memory
-
- strncpy(_ptr, s+pos, len); // copy the substring
- _ptr[len] = '\0'; // need to NULL terminate
- }
-
- string::string(const string& s, unsigned pos, unsigned len)
- {
- int s_len = s.Len();
-
- if(pos > s_len)
- pos = s_len;
- if(len > s_len - pos)
- len = s_len - pos;
-
- _ptr = new char[len+1]; // allocate new memory
-
- strncpy(_ptr, s(pos), len); // copy the substring
- _ptr[len] = '\0'; // need to NULL terminate
- }
-
- string::string(long n)
- {
- char tmp[15];
- ltoa(n, tmp, 10);
-
- _ptr = new char[strlen(tmp) + 1];
- strcpy(_ptr, tmp);
- }
-
- string::~string(void)
- {
- if(_ptr)
- delete _ptr;
- }
-
- /* -------------------------------------------------------------------- */
-
- string& string::Right(unsigned len)
- {
- Mid(this->Len()-len, len);
- return *this;
- }
-
- string& string::Left(unsigned len)
- {
- Mid(0, len);
- return *this;
- }
-
- string& string::Mid(unsigned pos, unsigned len)
- {
- int s_len = Len();
-
- if(pos > s_len)
- pos = s_len;
- if(len > s_len - pos)
- len = s_len - pos;
-
- char *tmp = new char[len+1]; // allocate new memory
-
- strncpy(tmp, _ptr+pos, len); // copy the substring
- tmp[len] = '\0'; // need to NULL terminate
-
- delete _ptr;
- _ptr = tmp;
- return *this;
- }
-
- string& string::Justify(int mode, unsigned len, int clip)
- {
- Trim(); // delete outter whitespace
-
- int this_len = Len();
-
- if(this_len >= len && clip == 0) // check for out-of-bounds
- return *this;
-
- if(this_len > len && clip == 1) // check for clipping
- {
- if(mode == LEFT)
- Left(len);
- else if(mode == CENTER)
- Mid((this_len-len)/2, len);
- else if(mode == RIGHT)
- Right(len);
-
- return *this; // return clipped string
- }
-
- if(mode == LEFT)
- *this = *this + string(' ', len-this_len);
- else if(mode == CENTER)
- *this = string(' ', (len-this_len)/2) + *this + string(' ', len - (len+this_len)/2);
- else if(mode == RIGHT)
- *this = string(' ', len-this_len) + *this;
-
- return *this; // return normal string
- }
-
- string& string::toUpper(void)
- {
- for(int i=0; i<strlen(_ptr); i++)
- _ptr[i] = ::toupper(_ptr[i]);
- return *this;
- }
-
- string& string::toLower(void)
- {
- for(int i=0; i<strlen(_ptr); i++)
- _ptr[i] = ::tolower(_ptr[i]);
- return *this;
- }
-
- int& string::Value(int& n)
- {
- n = atoi(_ptr);
- return n;
- }
-
- long& string::Value(long& n)
- {
- n = atol(_ptr);
- return n;
- }
-
- string& string::Insert(unsigned pos, const string& s)
- {
- int this_len = this->Len();
- int s_len = s.Len();
-
- if(pos > this_len)
- pos = this_len;
-
- char *tmp = new char[this_len + s_len + 1];
-
- strncpy(tmp, _ptr, pos);
- tmp[pos] = '\0';
- strcat(tmp, s.ptr());
- strcat(tmp, _ptr+pos);
-
- delete _ptr;
- _ptr = tmp;
- return *this;
- }
-
- string& string::Delete(unsigned pos, unsigned len)
- {
- int this_len = this->Len();
-
- if(pos >= this_len)
- return *this;
- if(len == 0)
- return *this;
- if(len > this_len - pos)
- len = this_len - pos;
-
- char *tmp = new char[this_len-len+1];
-
- strncpy(tmp, _ptr, pos);
- tmp[pos] = '\0';
- strcat(tmp, _ptr+pos+len);
-
- delete _ptr;
- _ptr = tmp;
- return *this;
- }
-
- char* string::Copy(char *s)
- {
- if(s)
- delete s;
- s = new char[Len() + 1];
- strcpy(s, _ptr);
-
- return s;
- }
-
- string& string::Trim(int mode, char ch)
- {
- int begin = 0;
- int end = this->Len()-1;
-
- if(ch == WHITESPACE) // if we're deleting whitespaces...
- {
- if(mode == LEFT || mode == CENTER) // delete leading whitespace
- {
- while(isspace(_ptr[begin]) && begin <= end)
- begin++;
- }
-
- if(mode == RIGHT || mode == CENTER) // delete trailing whitespace
- {
- while(isspace(_ptr[end]) && end >= begin)
- end--;
- }
- }
- else // else a character was specified
- {
- if(mode == LEFT || mode == CENTER) // delete leading characters
- {
- while(_ptr[begin] == ch && begin <= end)
- begin++;
- }
-
- if(mode == RIGHT || mode == CENTER) // delete trailing characters
- {
- while(_ptr[end] == ch && end >= begin)
- end--;
- }
- }
-
- int s_len = end-begin+1;
- char *tmp = new char[s_len + 1];
- strncpy(tmp, _ptr+begin, s_len);
- tmp[s_len] = '\0';
-
- delete _ptr;
- _ptr = tmp;
- return *this;
- }
-
- /* ----- Operators ---------------------------------------------------- */
-
- string string::operator()(unsigned pos, unsigned len) const
- {
- string tmp(this->_ptr, pos, len);
- return tmp;
- }
-
- // =
- string& string::operator=(const char ch)
- {
- if(_ptr)
- delete _ptr;
-
- _ptr = new char[2];
- _ptr[0] = ch;
- _ptr[1] = '\0';
-
- return *this;
- }
-
- string& string::operator=(const char *s)
- {
- char *tmp = _ptr; // don't delete _ptr yet
- _ptr = new char[strlen(s)+1];
- strcpy(_ptr, s);
-
- if(tmp)
- delete tmp;
- return *this;
- }
-
- string& string::operator=(const string& s)
- {
- char *tmp = _ptr; // don't delete _ptr yet
- _ptr = new char[s.Len()+1];
- strcpy(_ptr, s.ptr());
-
- if(tmp)
- delete tmp;
- return *this;
- }
-
- string& string::operator=(const int n)
- {
- if(_ptr)
- delete _ptr;
-
- char tmp[15];
- itoa(n, tmp, 10);
-
- _ptr = new char[strlen(tmp) + 1];
- strcpy(_ptr, tmp);
-
- return *this;
- }
-
- // +
- string operator+(const string& s1, const char *s2)
- {
- string tmp(s1);
- tmp += s2;
- return tmp;
- }
-
- string operator+(const char *s1, const string& s2)
- {
- string tmp(s1);
- tmp += s2;
- return tmp;
- }
-
- string operator+(const string& s1, const string& s2)
- {
- string tmp(s1);
- tmp += s2;
- return tmp;
- }
-
- // +=
- string& string::operator+=(const char ch)
- {
- char *tmp = _ptr;
- int this_len = this->Len();
-
- _ptr = new char[this_len + 2];
-
- strcpy(_ptr, tmp);
- _ptr[this_len] = ch;
- _ptr[this_len+1] = '\0';
-
- if(tmp)
- delete tmp;
- return *this;
- }
-
- string& string::operator+=(const char *s)
- {
- char *tmp = _ptr;
-
- _ptr = new char[strlen(tmp) + strlen(s) + 1];
-
- strcpy(_ptr, tmp);
- strcat(_ptr, s);
-
- if(tmp)
- delete tmp;
- return *this;
- }
-
- string& string::operator+=(const string& s)
- {
- char *tmp = _ptr;
- _ptr = new char[strlen(tmp) + s.Len() + 1];
-
- strcpy(_ptr, tmp);
- strcat(_ptr, s.ptr());
-
- if(tmp)
- delete tmp;
- return *this;
- }
-
- // *
- string operator*(const string& s1, int n)
- {
- string tmp(s1);
-
- for(int i=1; i<n; i++)
- tmp += s1;
- return tmp;
- }
-
- // *=
- string& string::operator*=(unsigned n)
- {
- char *tmp = _ptr;
-
- _ptr = new char[n*strlen(tmp) + 1];
-
- strcpy(_ptr, tmp);
- for(int i=1; i<n; i++)
- strcat(_ptr, tmp);
-
- if(tmp)
- delete tmp;
- return *this;
- }
-
- // []
- char& string::operator[](unsigned n) const
- {
- if(n >= Len())
- n = Len()-1;
- return *(_ptr + n);
- }
-
- /* -------------------------------------------------------------------- */
- /* AWK-style functions */
- /* -------------------------------------------------------------------- */
-
- int index(const string& s, const string& t)
- {
- int pos;
- char *tmp;
-
- if((tmp = strstr(s.ptr(), t.ptr())) != NULL)
- pos = (int)(tmp-(const)s.ptr());
- else
- pos = -1;
-
- return pos;
- }
-
- string substr(const string& s, unsigned p, unsigned n)
- {
- string tmp = mid(s, p, n);
- return tmp;
- }
-
- int split(const string& s, string **array, const string& fs)
- {
- int i=0, j=1, start=0;
- int fs_len = fs.Len();
- int s_len = s.Len();
- string *tmp;
-
- while(i < s_len)
- {
- if(strncmp(s(i), fs(), fs_len) == 0)
- j++;
- i++;
- }
- tmp = new string[j];
- i = 0;
- j = 0;
-
- while(i < s_len)
- {
- if(strncmp(s(i), fs(), fs_len) == 0)
- {
- tmp[j++] = string(mid(s, start, i-start));
- i += fs_len;
- start = i;
- }
- else
- i++;
- }
- tmp[j++] = mid(s, start, i-start);
-
- *array = tmp;
- return j;
- }
-
- int gsub(const string& from, const string& to, string& str, unsigned count)
- {
- int i=0, j=0;
- int from_len, to_len;
-
- from_len = from.Len();
- to_len = to.Len();
-
- while(i <= str.Len()-from_len)
- {
- if(strncmp(str(i), from(), from_len) == 0)
- {
- str = left(str, i) + to + right(str, str.Len()-i-from_len);
- i += to_len;
- if(++j == count)
- break;
- }
- else
- i++;
- }
- return j;
- }
-
- /* -------------------------------------------------------------------- */
- /* C-style functions */
- /* -------------------------------------------------------------------- */
-
- string toupper(const string& s)
- {
- string tmp(s);
- tmp.toupper();
- return tmp;
- }
-
- string tolower(const string& s)
- {
- string tmp(s);
- tmp.tolower();
- return tmp;
- }
-
- string left(const string& s, unsigned len)
- {
- string tmp(s, 0, len);
- return tmp;
- }
-
- string right(const string& s, unsigned len)
- {
- string tmp(s, s.Len()-len, len);
- return tmp;
- }
-
- string mid(const string& s, unsigned pos, unsigned len)
- {
- string tmp(s, pos, len);
- return tmp;
- }
-
- string justify(const string& s, int mode, unsigned len, int clip)
- {
- string tmp(s);
- tmp.Justify(mode, len, clip);
- return tmp;
- }
-
- string trim(const string& s, int mode)
- {
- string tmp(s);
- tmp.Trim(mode);
- return tmp;
- }
-
- /* ----- Stream I/O --------------------------------------------------- */
-
- ostream& operator<<(ostream& s, const string& str)
- {
- return s << str();
- }
-
- istream& operator>>(istream& s, string& str)
- {
- char p[256];
-
- s >> p;
- str = p;
-
- return s;
- }
-
-