12

String

  1. #if !defined( _MYSTRING_H )
  2. #define _MYSTRING_H
  3.  
  4. #include <iostream>
  5.  
  6. using namespace std;
  7.  
  8. class String {
  9.     friend bool operator==( const String &, const String & );
  10.     friend bool operator!=( const String &, const String & );
  11.     friend bool operator<( const String &, const String & );
  12.     friend bool operator<=( const String &, const String & );
  13.     friend bool operator>( const String &, const String & );
  14.     friend bool operator>=( const String &, const String & );
  15.     friend String operator+( const String &, const String & );
  16.     friend ostream &operator<<( ostream &, const String & );
  17.     friend istream &operator>>( istream &, String & );
  18.  
  19. private:
  20.     unsigned len;
  21.     char *buf;
  22.  
  23. public:
  24.     ~String( );
  25.     String( unsigned =0 );
  26.     String( char, unsigned );
  27.     String( const char * );
  28.     String( const String &r );
  29.  
  30. #if 1
  31.     String &operator=( const String & );
  32. #endif
  33.     String &operator+=( const String & );
  34.  
  35.     char &operator[]( int ) const;
  36.  
  37.     operator const char *() const;
  38.  
  39.     unsigned length( ) const { return len; };
  40.  
  41.     istream &getline( istream &, char );
  42.  
  43.     void append( String & );
  44.     void put( String &, int );
  45.     void insert( String &, int );
  46.     void remove( int, int =1 );
  47.     void erase( );
  48.  
  49. #if defined( STANDALONE )
  50.     void print( const char * =0 ) const;
  51. #endif
  52.  
  53. };
  54.  
  55. #endif
  1. #include "String.h"
  2.  
  3. #include <iostream>
  4. #include <string.h>
  5. #include <memory.h>
  6. #include <assert.h>
  7.  
  8. using namespace std;
  9.  
  10. #ifdef DEBUG
  11. int debug = 1;  // 0 - off, 1 - on
  12. #endif
  13.  
  14. #ifdef DEBUG
  15. #define ONDEBUG( expr ) do { if ( debug ) { expr; } } while ( 0 )
  16. #else
  17. #define ONDEBUG( expr )
  18. #endif
  19.  
  20. String::~String( )
  21. {
  22.     ONDEBUG( cout << "String::~String()\n"; );
  23.  
  24.     delete [] buf;
  25. }
  26.  
  27. String::String( unsigned n ) : len( n )
  28. {
  29.     ONDEBUG( cout << "String::String( unsigned n=" << n << " )\n"; );
  30.  
  31.     buf = new char[ len+1 ];
  32.     for( int i = 0; i < len; i++ )
  33.         buf[ i ] = ' '; // fill with spaces
  34.     buf[ len ] = '\0';
  35. }
  36.  
  37. String::String( char c, unsigned n) : len( n )
  38. {
  39.     ONDEBUG( cout << "String::String( char c=" << c << ", unsigned n=" << n << " )\n"; );
  40.  
  41.     buf = new char[ len+1 ];
  42.     for( int i = 0; i < len; i++ )
  43.         buf[ i ] = c;   // fill with char
  44.     buf[ len ] = '\0';
  45. }
  46.  
  47. String::String( const char *s ) : len( strlen( s ) )    // legal!
  48. {
  49.     ONDEBUG( cout << "String::String( const char *s=\"" << s << "\" )\n"; );
  50.  
  51.     buf = new char[ len+1 ];
  52.     for( int i = 0; i < len; i++ )
  53.         buf[ i ] = s[ i ];  // copy string
  54.     buf[ len ] = '\0';
  55. }
  56.  
  57. String::String( const String &s ) : len( s.len )
  58. {
  59.     ONDEBUG( cout << "String::String( const String &s=" << &s << " )\n"; );
  60.  
  61.     buf = new char[ len+1 ];
  62.     for( int i = 0; i < s.len; i++ )
  63.         buf[ i ] = s.buf[ i ];  // copy string
  64.     buf[ len ] = '\0';
  65. }
  66.  
  67. String::operator const char *() const
  68. {
  69.     ONDEBUG( cout << "String::operator const char *\n"; );
  70.     return buf;
  71. }
  72.  
  73. #if 1
  74. String& String::operator=( const String &s )
  75. {
  76.     ONDEBUG( cout << "String::operator=( " << &s << " )\n"; );
  77.  
  78.     if ( &s == this )
  79.         return *this;
  80.  
  81.     len =  s.len;
  82.  
  83.     delete [] buf;
  84.  
  85.     buf = new char[ len+1 ];
  86.     strcpy( buf, s.buf );
  87.  
  88.     return *this;
  89. }
  90. #endif
  91.  
  92. String& String::operator+=( const String &s )
  93. {
  94.     ONDEBUG( cout << "String::operator+=( " << &s << " )\n"; );
  95.  
  96.     int nlen = len+s.len;
  97.     char *nbuf = new char[ nlen+1 ];
  98.  
  99.     strcpy( nbuf, buf );
  100.     strcpy( nbuf+len, s.buf );
  101.  
  102.     delete [] buf;
  103.  
  104.     len = nlen;
  105.     buf = nbuf;
  106.  
  107.     return *this;
  108. }
  109.  
  110. char &String::operator[]( int i ) const
  111. {
  112.     ONDEBUG( cout << "String::operator[ " << i << " ]\n"; );
  113.  
  114.     assert( i >= 0 && i < len );
  115.  
  116.     return buf[ i ];
  117. }
  118.  
  119. ostream &operator<<( ostream &ostr, const String &s )
  120. {
  121.     return ostr << s.buf;
  122. }
  123.  
  124. istream &operator>>( istream &istr, String &s )
  125. {
  126.     char nbuf[ 1024 ];  // reasonably large enough
  127.  
  128.     istr >> nbuf;
  129.  
  130.     s = nbuf;                       // explain!
  131.  
  132.     return istr;
  133. }
  134.  
  135. String operator+( const String &s1, const String &s2 )
  136. {
  137. #if 1
  138.     String s( s1.len + s2.len );
  139.  
  140.     strcpy( s.buf, s1.buf );
  141.     strcat( s.buf, s2.buf );
  142.  
  143.     return s;
  144. #else
  145.     char s[ s1.len + s2.len + 1 ];
  146.  
  147.     strcpy( s, s1.buf );
  148.     strcpy( s+s1.len, s2.buf );
  149.  
  150.     return String( s );
  151. #endif
  152. }
  153.  
  154. bool operator==( const String &s1, const String &s2 )
  155. {
  156. #if 0
  157.     return (strcmp( s1.buf, s2.buf ) == 0);
  158. #else
  159.     return (strcmp( s1, s2 ) == 0);     // using operator char *
  160. #endif
  161. }
  162.  
  163. bool operator!=( const String &s1, const String &s2 )
  164. {
  165. #if 0
  166.     return (strcmp( s1.buf, s2.buf ) != 0);
  167. #else
  168.     return (strcmp( s1, s2 ) != 0);     // using operator char *
  169. #endif
  170. }
  171.  
  172. bool operator>=( const String &s1, const String &s2 )
  173. {
  174. #if 0
  175.     return (strcmp( s1.buf, s2.buf ) >= 0);
  176. #else
  177.     return (strcmp( s1, s2 ) >= 0);     // using operator char *
  178. #endif
  179. }
  180.  
  181. bool operator<=( const String &s1, const String &s2 )
  182. {
  183. #if 0
  184.     return (strcmp( s1.buf, s2.buf ) <= 0);
  185. #else
  186.     return (strcmp( s1, s2 ) <= 0);     // using operator char *
  187. #endif
  188. }
  189.  
  190. bool operator>( const String &s1, const String &s2 )
  191. {
  192. #if 0
  193.     return (strcmp( s1.buf, s2.buf ) > 0);
  194. #else
  195.     return (strcmp( s1, s2 ) > 0);      // using operator char *
  196. #endif
  197. }
  198.  
  199. bool operator<( const String &s1, const String &s2 )
  200. {
  201. #if 0
  202.     return (strcmp( s1.buf, s2.buf ) < 0);
  203. #else
  204.     return (strcmp( s1, s2 ) < 0);      // using operator char *
  205. #endif
  206. }
  207.  
  208. istream &String::getline( istream &istr, char c='\n' )
  209. {
  210.     char nbuf[ 1024 ];  // reasonably large enough
  211.  
  212.     istr.getline( nbuf, 1024, c );
  213.  
  214.     if ( istr )
  215.     {
  216.         len = strlen( nbuf );
  217.         delete [] buf;
  218.         buf = new char[ len+1 ];
  219.         strcpy( buf, nbuf );
  220.     }
  221.     else
  222.     {
  223.         len = 0;
  224.         delete [] buf;
  225.         buf = new char[ len+1 ];
  226.         buf[ len ] = '\0';
  227.     }
  228.  
  229.     return istr;
  230. }
  231.  
  232. void String::append( String &s )
  233. {
  234.     int nlen = len+s.len;
  235.     char *nbuf = new char[ nlen+1 ];
  236.  
  237.     memcpy( nbuf, buf, len );
  238.     memcpy( nbuf+len, s.buf, s.len );
  239.     nbuf[ nlen ] = '\0';
  240.  
  241.     len = nlen;
  242.     buf = nbuf;
  243. }
  244.  
  245. void String::put( String &s, int w )
  246. {   // put s at position w - append if w<0 or w>=len
  247.     if ( w < 0 || w >= len )
  248.         append( s );
  249.     else if ( (w+s.len) > len )
  250.     {
  251.         int nlen = w + s.len;
  252.         char *nbuf = new char[ nlen+1 ];
  253.  
  254.         memcpy( nbuf, buf, w );
  255.         memcpy( nbuf+w, s.buf, s.len );
  256.         nbuf[ nlen ] = '\0';
  257.  
  258.         len = nlen;
  259.         buf = nbuf;
  260.     }
  261.     else
  262.         memcpy( buf+w, s.buf, s.len );
  263. }
  264.  
  265. void String::insert( String &s, int w )
  266. {   // insert s at position w - append if w<0 or w>=len
  267.     if ( w < 0 || w >= len )
  268.         append( s );
  269.     else
  270.     {
  271.         int nlen = len + s.len;
  272.         char *nbuf = new char[ nlen+1 ];
  273.  
  274.         memcpy( nbuf, buf, w );
  275.         memcpy( nbuf+w, s.buf, s.len );
  276.         memcpy( nbuf+w+s.len, buf+w, len-w );
  277.         nbuf[ nlen ] = '\0';
  278.  
  279.         len = nlen;
  280.         buf = nbuf;
  281.     }
  282. }
  283.  
  284. void String::erase( )
  285. {   // empty string
  286.     len = 0;
  287.     delete [] buf;
  288.     buf = new char[ 1 ];
  289.     buf[ 0 ] = '\0';
  290. }
  291.  
  292. void String::remove( int w, int n )
  293. {   // remove n characters at position w - remove all if n<0, from end if w<0 or w>=len
  294.     if ( n < 0 || n >= len )
  295.         erase();
  296.     else
  297.     {
  298.         if ( w < 0 || w >= len )
  299.             w = len - n;
  300.  
  301.         int nlen = len - n;
  302.         char *nbuf = new char[ nlen + 1 ];
  303.  
  304.         memcpy( nbuf, buf, w );
  305.         memcpy( nbuf+w, buf+w+n, nlen-w );
  306.         nbuf[ nlen ] = '\0';
  307.  
  308.         len = nlen;
  309.         buf = nbuf;
  310.     }
  311. }
  312.  
  313. #if defined( STANDALONE )
  314.  
  315. void String::print( const char *leading ) const
  316. {
  317.     if ( leading )
  318.         cout << leading;
  319.     cout << "this=" << this << " len=" << len << "\tbuf(" << &buf << ")=[" << buf << "]" << endl;
  320. }
  321.  
  322. int main() {
  323.     String s1;
  324.     s1.print();
  325.     String s2( 4 );
  326.     s2.print();
  327.     String s3( '@', 10 );
  328.     s3.print();
  329.     {
  330.     String s4( "ABC$DEF" );
  331.     s4.print();
  332.     }
  333.     const String s5( "DON'T CHANGE!" );
  334.     s5.print();
  335.  
  336.     cout << endl;
  337.  
  338.     String john = "John";
  339.     john.print();
  340.     cout << john << endl;
  341.     String paul;
  342.     paul = "Paul";      // calls a constructor!
  343.     paul.print();
  344.     cout << paul << endl;
  345.  
  346.     // try this without defining operator=
  347.     john = paul;
  348.     john.print();
  349.     paul[0] = 'S';
  350. //  paul.operator[](0) = 'S';   // if char &operator[]( unsigned ) const;
  351.     paul.print();
  352.     john.print();
  353.  
  354.     cout << ">>>>>\n";
  355.     {
  356.         String grand( "grand" );
  357.         String child( "child" );
  358.  
  359.         cout << "grand+child=\t[" << grand + child << "]\n";
  360.         cout << "grand+\"child\"=\t[" << grand + "child" << "]\n";
  361.     }
  362.     cout << "<<<<<\n";
  363.  
  364.     cout << ">>>>>\n";
  365.     {
  366.         String grand( "grand" );
  367.         String child( "child" );
  368.  
  369.         grand += child;
  370.  
  371.         cout << "grand+=child-> len=" << grand.length() << "\tbuf=[" << grand << "]\n";
  372.     }
  373.     cout << "<<<<<\n";
  374.  
  375.     String a, b;
  376.  
  377.     cout << "Enter 2 strings or ^D/^Z:\n";
  378.  
  379. #if 0
  380.     while ( cin >> a >> b ) {
  381. #else
  382.     while ( a.getline( cin ) && b.getline( cin ) ) {
  383. #endif
  384.         a.print( "a-> " ), b.print( "b-> " );
  385.  
  386.         if ( a == b )
  387.             cout << "\t[" << a << "]==[" << b << "]\n";
  388.         if ( a != b )
  389.             cout << "\t[" << a << "]!=[" << b << "]\n";
  390.         if ( a >= b )
  391.             cout << "\t[" << a << "]>=[" << b << "]\n";
  392.         if ( a <= b )
  393.             cout << "\t[" << a << "]<=[" << b << "]\n";
  394.         if ( a > b )
  395.             cout << "\t[" << a << "]>[" << b << "]\n";
  396.         if ( a < b )
  397.             cout << "\t[" << a << "]<[" << b << "]\n";
  398.  
  399.         cout << "Try again 2 strings or ^D/^Z:\n";
  400.     }
  401.  
  402.     {
  403.         char *hello = "Hello";
  404.         String s0 = hello;
  405.         String s1 = s0;
  406.         String s2 = " my dear";
  407.         String s3 = " my darling";
  408.         String s4 = " lovely";
  409.  
  410.         s1.print( "s1-> " );
  411.         s1.append( s2 );
  412.         s1.print( "s1-> " );
  413.  
  414.         s1 = s0;
  415.         s1.print( "s1-> " );
  416.         s1.put( s2, -1 );
  417.         s1.print( "s1-> " );
  418.         s1.put( s3, 5 );
  419.         s1.print( "s1-> " );
  420.         s1.put( s2, 5 );
  421.         s1.print( "s1-> " );
  422.  
  423.         s1 = s0;
  424.         s1.print( "s1-> " );
  425.         s1.insert( s4, 100 );
  426.         s1.print( "s1-> " );
  427.  
  428.         s1 = s0;
  429.         s1.print( "s1-> " );
  430.         s1.append( s2 );
  431.         s1.print( "s1-> " );
  432.         s1.insert( s4, 8 );
  433.         s1.print( "s1-> " );
  434.  
  435.         s1.erase();
  436.         s1.print( "s1-> " );
  437.         s1 = s0;
  438.         s1.append( s2 );
  439.         s1.print( "s1-> " );
  440.         s1.remove( 5, 3 );
  441.         s1.print( "s1-> " );
  442.         s1.remove( -1, 5 );
  443.         s1.print( "s1-> " );
  444.     }
  445.  
  446.     return 0;   // exit() doesn't call destructors
  447. }
  448.  
  449. #endif

Comments

Your comment:
[p] [b] [i] [u] [s] [quote] [pre] [br] [code] [url] [email] strip help 2000

Enter a maximum of 2000 characters.
Improve the presentation of your text with the following formatting tags:
[p]paragraph[/p], [b]bold[/b], [i]italics[/i], [u]underline[/u], [s]strike[/s], [quote]citation[/quote], [pre]as is[/pre], [br]line break,
[url]http://www.izend.org[/url], [url=http://www.izend.org]site[/url], [email]izend@izend.org[/email], [email=izend@izend.org]izend[/email],
[code]command[/code], [code=language]source code in c, java, php, html, javascript, xml, css, sql, bash, dos, make, etc.[/code].