// // simplified version of the string class // matching the specifications of the STL // // Described in Chapter 7 of // Data Structures in C++ using the STL // Published by Addison-Wesley, 1997 // Written by Tim Budd, budd@cs.orst.edu // Oregon State University // # include "simstring.h" # include # include string::string () // default constructor, length zero { buffer = 0; resize (0, ' '); // allocate buffer of length zero } string::string (char * cp) // initialize string from literal C-style string { buffer = 0; resize (strlen(cp), ' '); // allocate buffer of correct size strcpy (buffer, cp); // then fill with values } string::string (string & str) // initialize string from argument string { buffer = 0; resize (str.length(), ' '); // allocate buffer of correct size strcpy (buffer, str.buffer); // then fill with values } void string::operator = (string & str) // reassign string to the argument value { resize (str.length(), ' '); strcpy (buffer, str.buffer); } string::~string() // called implicitly when a string is about to be deleted // free the memory associated with the buffer { delete [ ] buffer; } void string::resize (unsigned int newLength, char pad) { // if no current buffer, length is zero if (buffer == 0) bufferLength = 0; // case 1, getting smaller if (newLength < bufferLength) { // just add new null character buffer[newLength] = '\0'; } else { // case 2, getting larger // allocate new buffer, allow space for null character int i; char * newbuffer = new char[newLength + 1]; assert (newbuffer != 0); // first copy existing characters for (i = 0; i < bufferLength && buffer[i] != '\0'; i++) newbuffer[i] = buffer[i]; // then add pad characters for ( ; i < newLength; i++) newbuffer[i] = pad; // add terminating null character newbuffer[i] = '\0'; // free up old area, assign new if (buffer != 0) delete [ ] buffer; buffer = newbuffer; bufferLength = newLength; } } int string::length () // return number of characters in string { for (int i = 0; i < bufferLength; i++) if (buffer[i] == '\0') return i; return bufferLength; } bool string::empty () // see if string is empty { return buffer[0] == '\0'; } char & string::operator [ ] (unsigned int index) // return reference to character at location { assert (index <= bufferLength); // not required by standard return buffer[index]; } string string::substr (unsigned int start, unsigned int len) // return a subportion of string { assert (start + len <= length()); string sub; // create new value sub.resize (len, ' '); // resize appropriately for (int i = 0; i < len; i++) sub[i] = buffer[start + i]; // copy characters return sub; } char * string::begin () // return starting iterator, just use pointer to buffer { return buffer; } char * string::end () // return past-the-end iterator { return buffer + length(); } void string::remove (unsigned int start, unsigned int len) // remove len characters from given location { // compute end of deleted run int stop = start + len; // move characters into place while ((stop < bufferLength) && (buffer[stop] != '\0')) buffer[start++] = buffer[stop++]; buffer[start] = '\0'; } void string::insert (unsigned int position, string & newText) // insert text, starting at position { int len = length(); // current length int ntLen = newText.length(); // additional length int newLen = len + ntLen; // new length // if necessary, resize buffer resize(newLen, '\0'); // move existing characters over for (int i = len; i > position; i--) buffer[i + ntLen] = buffer[i]; // insert new characters for (int i = 0; i < ntLen; i++) buffer[position + i] = newText[i]; } void string::replace (unsigned start, unsigned len, string & newText) // replace start to start + len with new text { remove (start, len); insert (start, newText); } void string::operator += (string & right) // append argument string to end of current string { insert (length(), right); } string operator + (string & left, string & right) // catenate two string values, forming a new string { string clone(left); // copy left argument clone += right; // append right argument return clone; // return result } # if 0 // already defined, this gives compile errors int operator < (string & left, string & right) // test if left string is lexicographically less than right string { return strcmp(left.buffer, right.buffer) < 0; } # endif int string::find (string & target, unsigned int start) // search for target string as a substring { int targetLength = target.length(); // stop is last possible starting position int stop = length() - targetLength; for (int i = start; i <= stop; i++) { string text = substr(i, targetLength); if (text == target) return i; } // no match found, return out of bound index return bufferLength; }