// // ============================================================ // // STring // // ============================================================ // // // Copyright (C) 1998 // // Professor Kenneth I. Joy // Computer Science Department // University of California // Davis, CA 95616 // // Permission is granted to use at your own risk and // distribute this software in source and binary forms // provided the above copyright notice and this paragraph // are preserved on all copies. This software is provided // "as is" with no express or implied warranty. // // // ============================================================ // #include #include #include #include #include #include #include "STring.h" #define TRUE 1 #define FALSE 0 /* ========================================================== CONSTRUCTORS, DESTRUCTOR ========================================================== */ STring :: STring () { _string = NULL ; _length = 0 ; } STring :: STring ( const char c ) { _string = new char[2] ; _length = 1 ; _string[0] = c ; ; _string[1] = '\0' ; ; } STring :: STring ( const int n ) { ostrstream os ; os << n << ends ; char * s = os.str() ; _length = strlen ( s ) ; _string = new char[_length+1] ; for ( int i = 0 ; i < _length ; i++ ) _string[i] = s[i] ; _string[_length] = '\0' ; delete s ; } STring :: STring ( const double d ) { ostrstream os ; os << d << ends ; char * s = os.str() ; _length = strlen ( s ) ; _string = new char[_length+1] ; for ( int i = 0 ; i < _length ; i++ ) _string[i] = s[i] ; _string[_length] = '\0' ; delete s ; } STring :: STring ( const char * s ) { _length = strlen ( s ) ; _string = new char[_length+1] ; for ( int i = 0 ; i <= _length ; i++ ) _string[i] = s[i] ; } STring :: STring ( const STring& s ) { _string = NULL ; _length = s._length ; if ( _length != 0 ) { _string = new char[_length+1] ; for ( int i = 0 ; i <= _length ; i++ ) _string[i] = s._string[i] ; } } STring :: ~STring () { delete [] _string ; _length = 0 ; } /* ========================================================== OPERATOR= ========================================================== */ STring& STring :: operator= ( const char * s ) { if ( _string != NULL ) { delete [] _string ; _length = 0 ; } _length = strlen ( s ) ; if ( _length > 0 ) { _string = new char[_length+1] ; for ( int i = 0 ; i <= _length ; i++ ) _string[i] = s[i] ; } else { _string = NULL ; } return ( *this ) ; } STring& STring :: operator= ( const STring& s ) { if ( this == &s ) return ( *this ) ; if ( _length > 0 ) delete [] _string ; _length = s._length ; if ( s._length > 0 ) { _string = new char[s._length+1] ; for ( int i = 0 ; i <= s._length ; i++ ) _string[i] = s._string[i] ; } else { _string = NULL ; } return ( *this ) ; } /* ========================================================== TYPE CONVERSION ========================================================== */ int STring :: int_value () const { if ( _length == 0 ) { cerr << "Cannot convert a zero length string " << " to a numeric" << endl ; abort() ; } if ( ! is_integer() ) { cerr << "Cannot convert string [" << *this << "] to an integer numeric string" << endl ; abort() ; } return ( atoi ( _string ) ) ; } double STring :: double_value () const { if ( _length == 0 ) { cerr << "Cannot convert a zero length string " << " to a numeric" << endl ; abort() ; } if ( ! is_numeric() ) { cerr << "Cannot convert string [" << *this << "] to a double numeric string" << endl ; abort() ; } double d = atof ( _string ) ; return ( d ) ; } /* ========================================================== OPERATOR[] ========================================================== */ char& STring :: operator[] ( int i ) { if ( ( i >= _length ) || ( i < 0 ) ) { cerr << "Cannot access character " << i << "of string " << *this << endl ; abort() ; } return ( _string[i] ) ; } /* ========================================================== OPERATOR() ========================================================== */ STring STring :: operator() ( const int i, const int n ) const { if ( ( n < 0 ) || ( i < 0 ) || ( n > _length ) || ( i > _length ) || ( n < i ) ) { cerr << "Illegal Substring Values " << i << " to " << n << endl ; abort() ; } STring s ; s._length = n - i + 1 ; s._string = new char [ s._length + 1 ] ; int k = i ; for ( int j = 0 ; j < s._length ; j++ ) { s._string[j] = _string[k] ; k++ ; } s._string[s._length] = '\0' ; return ( s ) ; } /* ========================================================== COMPARISON OPERATORS ========================================================== */ int operator== ( const STring& s1, const STring& s2 ) { if ( s1._length != s2._length ) return ( FALSE ) ; for ( int i = 0 ; i < s1._length ; i++ ) if ( s1._string[i] != s2._string[i] ) return ( FALSE ) ; return ( TRUE ) ; } int operator!= ( const STring& s1, const STring& s2 ) { if ( s1._length != s2._length ) return ( TRUE ) ; for ( int i = 0 ; i < s1._length ; i++ ) if ( s1._string[i] != s2._string[i] ) return ( TRUE ) ; return ( FALSE ) ; } int operator<= ( const STring& s1, const STring& s2 ) { if ( strcmp ( s1._string, s2._string ) <= 0 ) return ( TRUE ) ; return ( FALSE ) ; } int operator>= ( const STring& s1, const STring& s2 ) { if ( strcmp ( s1._string, s2._string ) >= 0 ) return ( TRUE ) ; return ( FALSE ) ; } int operator< ( const STring& s1, const STring& s2 ) { if ( strcmp ( s1._string, s2._string ) < 0 ) return ( TRUE ) ; return ( FALSE ) ; } int operator> ( const STring& s1, const STring& s2 ) { if ( strcmp ( s1._string, s2._string ) > 0 ) return ( TRUE ) ; return ( FALSE ) ; } int STring :: has_substring ( const STring& s ) const { if ( s._length == 0 ) return ( FALSE ) ; int n = Length() - s.Length() ; for ( int i = 0 ; i <= n ; i++ ) { int found = TRUE ; for ( int j = i , k = 0 ; k < s._length ; j++, k++ ) { if ( _string[j] != s._string[k] ) { found = FALSE ; break ; } } if ( found ) { return ( i ) ; } } return ( FALSE ) ; } /* ========================================================== CONCATENATE OPERATORS ========================================================== */ STring operator+ ( const STring& s1, const STring& s2 ) { STring s = s1 ; s += s2 ; return ( s ) ; } STring operator+ ( const STring& s1, const char * s2 ) { STring s = s1 ; s += STring ( s2 ) ; return ( s ) ; } STring operator+ ( const char * s1, const STring & s2 ) { STring s = s1 ; s += s2 ; return ( s ) ; } STring operator+ ( const STring& s1, const char s2 ) { STring s = s1 ; s += STring ( s2 ) ; return ( s ) ; } STring operator+ ( const char s1, const STring & s2 ) { STring s = STring ( s1 ) ; s += s2 ; return ( s ) ; } STring& STring :: operator+= ( const STring& s ) { if ( s.Length() == 0 ) return ( *this ) ; char * p = _string ; _string = new char [ _length + s._length + 1 ] ; int k = 0 ; for ( int i = 0 ; i < _length ; i++ ) { _string[k] = p[i] ; k++ ; } for ( int j = 0 ; j < s._length ; j++ ) { _string[k] = s._string[j] ; k++ ; } _length += s._length ; _string[_length] = '\0' ; delete p ; return ( *this ) ; } STring& STring :: operator+= ( const char * s ) { operator+= ( STring ( s ) ) ; return ( *this ) ; } STring& STring :: operator+= ( const char s ) { operator+= ( STring ( s ) ) ; return ( *this ) ; } /* ========================================================== OUTPUT ========================================================== */ ostream& operator<< ( ostream& co, const STring& s ) { return ( s.output ( co ) ) ; } /* ========================================================== OUTPUT ========================================================== */ ostream& STring :: output ( ostream& co, const int indent ) const { for ( int i = 0 ; i < indent ; i++ ) co << " " ; if ( _length == 0 ) co << "NullString" ; else co << _string ; return ( co ) ; } /* ========================================================== INPUT ========================================================== */ istream& operator>> ( istream& ci, STring& s ) { char c[80], cc ; // Getting rid of the preceeding // whitespace while ( TRUE ) { ci.get ( cc ) ; if ( ci.eof() ) { s = NullString ; return ci ; } if ( ( cc != ' ' ) && ( cc != '\t' ) && ( cc != '\n' ) ) { ci.putback ( cc ) ; break ; } } if ( ci.eof() ) { s = NullString ; return ci ; } // Now getting the string int k = 0 ; while ( TRUE ) { ci.get( cc ) ; if ( ci.eof() ) break ; if ( ( cc == ' ' ) || ( cc == '\t' ) || ( cc == '\n' ) || ( cc == ',' ) || ( cc == '(' ) || ( cc == ')' ) || ( cc == '[' ) || ( cc == ']' ) ) { if ( k > 0 ) { ci.putback ( cc ) ; } else { c[0] = cc ; k++ ; } break ; } c[k] = cc ; k++ ; if ( k > 80 ) { c[k] = '\0' ; cerr << "Input string is too long" << endl << " [" << c << "]" << endl ; abort() ; } } if ( ci.eof() ) { s = NullString ; } else { c[k] = '\0' ; s = c ; } return ci ; } /* ========================================================== IS_NUMERIC ========================================================== */ int STring :: is_integer() const { if ( strspn ( _string, "0123456789" ) != _length ) return ( FALSE ) ; else return ( TRUE ) ; } int STring :: is_numeric() const { if ( strspn ( _string, "0123456789.+-e" ) != _length ) return ( FALSE ) ; else return ( TRUE ) ; } /* ========================================================== LENGTH ========================================================== */ int STring :: Length() const { return _length ; } /* ========================================================== TOKEN ========================================================== */ STring STring :: token () // This routine returns the first non-white-space // token string from the STring instance // // side effect : The STring instance is modified // by removing the returned token from // the string. { STring s ; if ( _length == 0 ) { return ( s ) ; } char *p = new char [_length+1] ; int first_non_white_space = 0 ; for ( int i = 0 ; i < _length ; i++ ) { if ( ! isspace ( _string[i] ) ) break ; first_non_white_space++ ; } if ( first_non_white_space >= _length ) { return ( s ) ; } int j = 0 ; int last_character = first_non_white_space ; for ( i = first_non_white_space ; i < _length ; i++ ) { if ( ispunct( _string[i] ) || isspace ( _string[i] ) ) break ; p[j] = _string[i] ; last_character = i ; j++ ; } if ( j == 0 ) { p[0] = _string[0] ; j = 1 ; // I must return at least one char } p[j] = '\0' ; s._length = j ; s._string = new char [ s._length+1 ] ; for ( i = 0 ; i <= j ; i++ ) { s._string[i] = p[i] ; } if ( last_character >= _length-1 ) { delete [] _string ; _length = 0 ; } else { int k = 0 ; for ( i = last_character+1 ; i < _length ; i++ ) { _string[k] = _string[i] ; k++ ; } _string[k] = '\0' ; _length = k ; } delete [] p ; return s ; } /* ========================================================== REPEAT ========================================================== */ STring repeat ( const STring& s, const int n ) { STring ss ; for ( int i = 0 ; i < n ; i++ ) { ss += s ; } return ( ss ) ; } /* ========================================================== STRING ========================================================== */ char * STring :: string () const { char *p = new char[_length+1] ; for ( int i = 0 ; i <= _length ; i++ ) p[i] = _string[i] ; return p ; } /* ========================================================== LOWERCASE ========================================================== */ void STring :: lowercase () { for ( int i = 0 ; i <= _length ; i++ ) _string[i] = tolower ( _string[i] ) ; } /* ========================================================== BLANKS ========================================================== */ STring Blanks ( const int n ) { STring s ; for ( int i = 0 ; i <= n ; i++ ) s += " " ; return ( s ) ; }