home *** CD-ROM | disk | FTP | other *** search
/ C!T ROM 2 / ctrom_ii_b.zip / ctrom_ii_b / PROGRAM / C / STRPP11 / STR.CPP < prev    next >
C/C++ Source or Header  |  1992-03-23  |  10KB  |  501 lines

  1. /* -------------------------------------------------------------------- */
  2. /* str.cpp                                                  */
  3. /*                                    */
  4. /* String++ Version 1.1                Last revised 03/23/92    */
  5. /*                                      */
  6. /* Enhanced string class for Turbo C++/Borland C++.            */
  7. /* Copyright 1991, 1992 by Carl W. Moreland                */
  8. /* This source code may be freely distributed as long as the copyright    */
  9. /* notice remains intact.                        */
  10. /* -------------------------------------------------------------------- */
  11.  
  12. #include <ctype.h>
  13. #include "str.h"
  14.  
  15. /* ----- Constructors/Destructors ------------------------------------- */
  16.  
  17. string::string()
  18. {
  19.   _ptr = new char[1];
  20.   _ptr[0] = '\0';
  21. }
  22.  
  23. string::string(const char c, unsigned int n)
  24. {
  25.   _ptr = new char[n+1];
  26.  
  27.   for(int i=0; i<n; i++)
  28.     _ptr[i] = c;
  29.   _ptr[i] = '\0';
  30. }
  31.  
  32. string::string(const char *s, unsigned int n)
  33. {
  34.   _ptr = new char[n*strlen(s)+1];
  35.  
  36.   strcpy(_ptr, s);
  37.   for(int i=1; i<n; i++)
  38.     strcat(_ptr, s);
  39. }
  40.  
  41. string::string(const string& s, unsigned int n)
  42. {
  43.   _ptr = new char[n*s.len()+1];
  44.  
  45.   strcpy(_ptr, s.ptr());
  46.   for(int i=1; i<n; i++)
  47.     strcat(_ptr, s.ptr());
  48. }
  49.  
  50. string::~string(void)
  51. {
  52.   if(_ptr)
  53.     delete _ptr;
  54. }
  55.  
  56. /* -------------------------------------------------------------------- */
  57.  
  58. string string::right(int len) const
  59. {
  60.   string tmp = this->mid(this->len()-len, len);
  61.   return tmp;
  62. }
  63.  
  64. string string::left(int len) const
  65. {
  66.   string tmp = this->mid(0, len);
  67.   return tmp;
  68. }
  69.  
  70. string string::mid(int pos, int len) const
  71. {
  72.   int this_len = this->len();
  73.  
  74.   if(pos > this_len)            // check for boundary errors
  75.     pos = this_len;
  76.   if(len > this_len - pos)
  77.     len = this_len - pos;
  78.  
  79.   char *tmp = new char[len+1];        // allocate new memory
  80.  
  81.   strncpy(tmp, _ptr+pos, len);        // copy the substring
  82.   tmp[len] = '\0';            // need to NULL terminate
  83.  
  84.   string str(tmp);            // need to return a string, not char*
  85.   delete tmp;                // done with tmp
  86.   return str;
  87. }
  88.  
  89. string string::justify(int mode, int len, int clip) const
  90. {
  91.   int begin, end, s_len;
  92.  
  93.   begin = 0;
  94.   end = this->len()-1;
  95.  
  96.   while(isspace(_ptr[begin]))        // delete leading whitespace
  97.     begin++;
  98.   while(isspace(_ptr[end]))        // delete trailing whitespace
  99.     end--;
  100.  
  101.   s_len = end-begin+1;
  102.   string tmp = this->mid(begin, s_len);    // get the rest of the string
  103.  
  104.   if(s_len >= len && clip == 0)        // check for out-of-bounds
  105.     return tmp;
  106.  
  107.   if(s_len > len && clip == 1)        // check for clipping
  108.   {
  109.     if(mode == LEFT_JUSTIFY)
  110.       tmp = tmp.left(len);
  111.     else if(mode == CENTER_JUSTIFY)
  112.       tmp = tmp.mid((tmp.len()-len)/2, len);
  113.     else if(mode == RIGHT_JUSTIFY)
  114.       tmp = tmp.right(len);
  115.  
  116.     return tmp;                // return clipped string
  117.   }
  118.  
  119.   if(mode == LEFT_JUSTIFY)
  120.     tmp += string(' ', len-s_len);
  121.   else if(mode == CENTER_JUSTIFY)
  122.     tmp = string(' ', (len-s_len)/2) + tmp + string(' ', len - (len+s_len)/2);
  123.   else if(mode == RIGHT_JUSTIFY)
  124.     tmp = string(' ', len-s_len) + tmp;
  125.  
  126.   return tmp;                // return normal string
  127. }
  128.  
  129. string& string::toupper(void)
  130. {
  131.   for(int i=0; i<strlen(_ptr); i++)
  132.     _ptr[i] = ::toupper(_ptr[i]);
  133.   return *this;
  134. }
  135.  
  136. string& string::tolower(void)
  137. {
  138.   for(int i=0; i<strlen(_ptr); i++)
  139.     _ptr[i] = ::tolower(_ptr[i]);
  140.   return *this;
  141. }
  142.  
  143. /* ----- Operators ---------------------------------------------------- */
  144.  
  145. // =
  146. string& string::operator=(const char ch)
  147. {
  148.   if(_ptr)
  149.     delete _ptr;
  150.  
  151.   _ptr = new char[2];
  152.   _ptr[0] = ch;
  153.   _ptr[1] = '\0';
  154.  
  155.   return *this;
  156. }
  157.  
  158. string& string::operator=(const char *s)
  159. {
  160.   char *tmp = _ptr;
  161.   _ptr = new char[strlen(s)+1];
  162.   strcpy(_ptr, s);
  163.  
  164.   if(tmp)
  165.     delete tmp;
  166.   return *this;
  167. }
  168.  
  169. string& string::operator=(const string& s)
  170. {
  171.   char *tmp = _ptr;
  172.   _ptr = new char[s.len()+1];
  173.   strcpy(_ptr, s.ptr());
  174.  
  175.   if(tmp)
  176.     delete tmp;
  177.   return *this;
  178. }
  179.  
  180. // +
  181. string operator+(const string& s1, const char *s2)
  182. {
  183.   string tmp(s1);
  184.   tmp += s2;
  185.   return tmp;
  186. }
  187.  
  188. string operator+(const char *s1, const string& s2)
  189. {
  190.   string tmp(s1);
  191.   tmp += s2;
  192.   return tmp;
  193. }
  194.  
  195. string operator+(const string& s1, const string& s2)
  196. {
  197.   string tmp(s1);
  198.   tmp += s2;
  199.   return tmp;
  200. }
  201.  
  202. // +=
  203. string& string::operator+=(const char ch)
  204. {
  205.   char *tmp = _ptr;
  206.   int this_len = this->len();
  207.  
  208.   _ptr = new char[this_len + 2];
  209.  
  210.   strcpy(_ptr, tmp);
  211.   _ptr[this_len]   = ch;
  212.   _ptr[this_len+1] = '\0';
  213.  
  214.   if(tmp)
  215.     delete tmp;
  216.   return *this;
  217. }
  218.  
  219. string& string::operator+=(const char *s)
  220. {
  221.   char *tmp = _ptr;
  222.  
  223.   _ptr = new char[strlen(tmp) + strlen(s) + 1];
  224.  
  225.   strcpy(_ptr, tmp);
  226.   strcat(_ptr, s);
  227.  
  228.   if(tmp)
  229.     delete tmp;
  230.   return *this;
  231. }
  232.  
  233. string& string::operator+=(const string& s)
  234. {
  235.   char *tmp = _ptr;
  236.   _ptr = new char[strlen(tmp) + s.len() + 1];
  237.  
  238.   strcpy(_ptr, tmp);
  239.   strcat(_ptr, s.ptr());
  240.  
  241.   if(tmp)
  242.     delete tmp;
  243.   return *this;
  244. }
  245.  
  246. // *
  247. string operator*(const string& s1, int n)
  248. {
  249.   string tmp(s1);
  250.  
  251.   for(int i=1; i<n; i++)
  252.     tmp += s1;
  253.   return tmp;
  254. }
  255.  
  256. // *=
  257. string& string::operator*=(int n)
  258. {
  259.   char *tmp = _ptr;
  260.  
  261.   _ptr = new char[n*strlen(tmp) + 1];
  262.  
  263.   strcpy(_ptr, tmp);
  264.   for(int i=1; i<n; i++)
  265.     strcat(_ptr, tmp);
  266.  
  267.   if(tmp)
  268.     delete tmp;
  269.   return *this;
  270. }
  271.  
  272. // []
  273. const char string::operator[](int n) const
  274. {
  275.   return *(_ptr + n);
  276. }
  277.  
  278. // ==
  279. int operator==(const string& s1, const char* s2)
  280. {
  281.   return strcmp(s1._ptr,s2)==0;
  282. }
  283.  
  284. int operator==(const char* s1, const string& s2)
  285. {
  286.   return strcmp(s1,s2._ptr)==0;
  287. }
  288.  
  289. int operator==(const string& s1, const string& s2)
  290. {
  291.   return strcmp(s1._ptr,s2._ptr)==0;
  292. }
  293.  
  294. // !=
  295. int operator!=(const string& s1, const char *s2)
  296. {
  297.   return strcmp(s1._ptr,s2)!=0;
  298. }
  299.  
  300. int operator!=(const char *s1, const string& s2)
  301. {
  302.   return strcmp(s1,s2._ptr)!=0;
  303. }
  304.  
  305. int operator!=(const string& s1, const string& s2)
  306. {
  307.   return strcmp(s1._ptr,s2._ptr)!=0;
  308. }
  309.  
  310. // <
  311. int operator<(const string& s1, const char *s2)
  312. {
  313.   return strcmp(s1._ptr,s2)< 0;
  314. }
  315.  
  316. int operator<(const char *s1, const string& s2)
  317. {
  318.   return strcmp(s1,s2._ptr)< 0;
  319. }
  320.  
  321. int operator<(const string& s1, const string& s2)
  322. {
  323.   return strcmp(s1._ptr,s2._ptr)< 0;
  324. }
  325.  
  326. // >
  327. int operator>(const string& s1, const char *s2)
  328. {
  329.   return strcmp(s1._ptr,s2)> 0;
  330. }
  331.  
  332. int operator>(const char *s1, const string& s2)
  333. {
  334.   return strcmp(s1,s2._ptr)> 0;
  335. }
  336.  
  337. int operator>(const string& s1, const string& s2)
  338. {
  339.   return strcmp(s1._ptr,s2._ptr)> 0;
  340. }
  341.  
  342. // <=
  343. int operator<=(const string& s1, const char *s2)
  344. {
  345.   return strcmp(s1._ptr,s2)<=0;
  346. }
  347.  
  348. int operator<=(const char *s1, const string& s2)
  349. {
  350.   return strcmp(s1,s2._ptr)<=0;
  351. }
  352.  
  353. int operator<=(const string& s1, const string& s2)
  354. {
  355.   return strcmp(s1._ptr,s2._ptr)<=0;
  356. }
  357.  
  358. // >=
  359. int operator>=(const string& s1, const char *s2)
  360. {
  361.   return strcmp(s1._ptr,s2)>=0;
  362. }
  363.  
  364. int operator>=(const char *s1, const string& s2)
  365. {
  366.   return strcmp(s1,s2._ptr)>=0;
  367. }
  368.  
  369. int operator>=(const string& s1, const string& s2)
  370. {
  371.   return strcmp(s1._ptr,s2._ptr)>=0;
  372. }
  373.  
  374. /* -------------------------------------------------------------------- */
  375. /* AWK-style functions                                                  */
  376. /* -------------------------------------------------------------------- */
  377.  
  378. int index(const string& s, const string& t)
  379. {
  380.   int pos;
  381.   char *tmp;
  382.  
  383.   if((tmp = strstr(s.ptr(), t.ptr())) != NULL)
  384.     pos = (int)(tmp-(const)s.ptr());
  385.   else
  386.     pos = -1;
  387.  
  388.   return pos;
  389. }
  390.  
  391. string substr(const string& s, unsigned int p, unsigned int n)
  392. {
  393.   string tmp = s.mid(p, n);
  394.   return tmp;
  395. }
  396.  
  397. int split(const string& s, string **array, const string& fs)
  398. {
  399.   int i=0, j=1, start=0;
  400.   int fs_len = fs.len();
  401.   int s_len = s.len();
  402.   string *tmp;
  403.  
  404.   while(i < s_len)
  405.   {
  406.     if(strncmp(s(i), fs(), fs_len) == 0)
  407.       j++;
  408.     i++;
  409.   }
  410.   tmp = new string[j];
  411.   i = 0;
  412.   j = 0;
  413.  
  414.   while(i < s_len)
  415.   {
  416.     if(strncmp(s(i), fs(), fs_len) == 0)
  417.     {
  418.       tmp[j++] = string(s.mid(start, i-start));
  419.       i += fs_len;
  420.       start = i;
  421.     }
  422.     else
  423.       i++;
  424.   }
  425.   tmp[j++] = s.mid(start, i-start);
  426.  
  427.   *array = tmp;
  428.   return j;
  429. }
  430.  
  431. int sub(const string& from, const string& to, string& str)
  432. {
  433.   return gsub(from, to, str, 1);
  434. }
  435.  
  436. int gsub(const string& from, const string& to, string& str, int count)
  437. {
  438.   int i=0, j=0;
  439.   int from_len, to_len;
  440.  
  441.   from_len = from.len();
  442.   to_len = to.len();
  443.  
  444.   while(i <= str.len()-from_len)
  445.   {
  446.     if(strncmp(str(i), from(), from_len) == 0)
  447.     {
  448.       str = str.left(i) + to + str.right(str.len()-i-from_len);
  449.       i += to_len;
  450.       if(++j == count)
  451.         break;
  452.     }
  453.     else
  454.       i++;
  455.   }
  456.   return j;
  457. }
  458.  
  459. /* -------------------------------------------------------------------- */
  460. /* C-style functions                            */
  461. /* -------------------------------------------------------------------- */
  462.  
  463. string toupper(const string& s)
  464. {
  465.   string tmp(s);
  466.   tmp.toupper();
  467.   return tmp;
  468. }
  469.  
  470. string tolower(const string& s)
  471. {
  472.   string tmp(s);
  473.   tmp.tolower();
  474.   return tmp;
  475. }
  476.  
  477. string right(const string& s, int len)
  478. {
  479.   string tmp = s.mid(s.len()-len, len);
  480.   return tmp;
  481. }
  482.  
  483. string left(const string& s, int len)
  484. {
  485.   string tmp = s.mid(0, len);
  486.   return tmp;
  487. }
  488.  
  489. string mid(const string& s, int pos, int len)
  490. {
  491.   string tmp = s.mid(pos, len);
  492.   return tmp;
  493. }
  494.  
  495. string justify(const string& s, int mode, int len, int clip)
  496. {
  497.   string tmp = s.justify(mode, len, clip);
  498.   return tmp;
  499. }
  500.  
  501.