// *******************************************************************
// Revised: January 13, 1998, <= and >= redefined using ! and <
// operator += now takes constant
// amortized time for adding one char
//
// Revised: November 19, 1998, replaced assert with exit: operator[]
// changed operator >> and getline
// so no limit on size of strings read
//
// APCS string class IMPLEMENTATION
//
// see apstring.h for complete documentation of functions
//
// string class consistent with a subset of the standard C++ string class
// as defined in the draft ANSI standard
// *******************************************************************
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <ctype.h>
#include "apstring.h"
const int npos = -1;
apstring::apstring()
// postcondition: string is empty
{
myLength = 0;
myCapacity = 1;
myCstring = new char[myCapacity];
myCstring[0] = '\0'; // make c-style string zero length
}
apstring::apstring(const char * s)
//description: constructs a string object from a literal string
// such as "abcd"
//precondition: s is '\0'-terminated string as used in C
//postcondition: copy of s has been constructed
{
assert (s != 0); // C-string not NULL?
myLength = strlen(s);
myCapacity = myLength + 1; // make room for '\0'
myCstring = new char[myCapacity];
strcpy(myCstring,s);
}
apstring::apstring(const apstring & str)
//description: copy constructor
//postcondition: copy of str has been constructed
{
myLength = str.length();
myCapacity = myLength + 1;
myCstring = new char[myCapacity];
strcpy(myCstring,str.myCstring);
}
apstring::~apstring()
//description: destructor
//postcondition: string is destroyed
{
delete[] myCstring; // free memory
}
const apstring& apstring::operator =(const apstring & rhs)
//postcondition: normal assignment via copying has been performed
{
if (this != &rhs) // check aliasing
{
if (myCapacity < rhs.length() + 1) // more memory needed?
{
delete[] myCstring; // delete old string
myCapacity = rhs.length() + 1; // add 1 for '\0'
myCstring = new char[myCapacity];
}
myLength = rhs.length();
strcpy(myCstring,rhs.myCstring);
}
return *this;
}
const apstring& apstring::operator = (const char * s)
//description: assignment from literal string such as "abcd"
//precondition: s is '\0'-terminated string as used in C
//postcondition: assignment via copying of s has been performed
{
int len = 0; // length of newly constructed string
assert(s != 0); // make sure s non-NULL
len = strlen(s); // # of characters in string
// free old string if necessary
if (myCapacity < len + 1)
{
delete[] myCstring; // delete old string
myCapacity = len + 1; // add 1 for '\0'
myCstring = new char[myCapacity];
}
myLength = len;
strcpy(myCstring,s);
return *this;
}
const apstring& apstring::operator = (char ch)
//description: assignment from character as though single char string
//postcondition: assignment of one-character string has been performed
{
if (myCapacity < 2)
{
delete [] myCstring;
myCapacity = 2;
myCstring = new char[myCapacity];
}
myLength = 1;
myCstring[0] = ch; // make string one character long
myCstring[1] = '\0';
return *this;
}
int apstring::length( ) const
//postcondition: returns # of chars in string
{
return myLength;
}
const char * apstring::c_str() const
//description: convert string into a '\0'-terminated string as
// used in C for use with functions
// that have '\0'-terminated string parameters.
//postcondition: returns the equivalent '\0'-terminated string
{
return myCstring;
}
char& apstring::operator[](int k)
// precondition: 0 <= k < length()
// postcondition: returns copy of the kth character
// note: if this reference is used to write a '\0'
// subsequent results are undefined
{
if (k < 0 || myLength <= k)
{
cerr << "index out of range: " << k << " string: " << myCstring
<< endl;
exit(1);
}
return myCstring[k];
}
char apstring::operator[](int k) const
// precondition: 0 <= k < length()
// postcondition: returns copy of the kth character
{
if (k < 0 || myLength <= k)
{
cerr << "index out of range: " << k << " string: " << myCstring
<< endl;
exit(1);
}
return myCstring[k];
}
ostream& operator <<(ostream & os, const apstring & str)
//postcondition: str is written to output stream os
{
return os << str.c_str();
}
istream& operator >>(istream & is, apstring & str)
//precondition: input stream is open for reading
//postcondition: the next string from input stream is has been read
// and stored in str
{
char ch;
str = ""; // empty string, will build one char at-a-time
is >> ch; // whitespace skipped, first non-white char in ch
if (! is.fail())
{
do
{
str += ch;
is.get(ch);
} while (! is.fail() && ! isspace(ch));
if (isspace(ch)) // put whitespace back on the stream
{
is.putback(ch);
}
}
return is;
}
istream & getline(istream & is, apstring & str)
//description: reads a line from input stream is into the string str
//precondition: input stream is open for reading
//postcondition: chars from input stream is up to '\n' have been read
{
char ch;
str = ""; // empty string, will build one char at-a-time
while (is.get(ch) && ch != '\n')
{
str += ch;
}
return is;
}
const apstring& apstring::operator +=(const apstring & str)
//postcondition: concatenates a copy of str onto this string
{
apstring copystring(str); // copy to avoid aliasing problems
int newLength = length() + str.length(); // self + added string
int lastLocation = length(); // index of '\0'
// check to see if local buffer not big enough
if (newLength >= myCapacity)
{
myCapacity = newLength + 1;
if (str.length() == 1) // special case for catenating one char
{ // make room for future catenations
myCapacity *= 2;
}
char * newBuffer = new char[myCapacity];
strcpy(newBuffer,myCstring); // copy into new buffer
delete [] myCstring; // delete old string
myCstring = newBuffer;
}
// now catenate str (copystring) to end of myCstring
strcpy(myCstring+lastLocation,copystring.c_str() );
myLength = newLength; // update information
return *this;
}
const apstring & apstring::operator += ( char ch )
// postcondition: concatenates a copy of ch onto this string
{
apstring temp; // make string equivalent of ch
temp = ch;
*this += temp;
return *this;
}
apstring operator +(const apstring & lhs, const apstring & rhs)
// postcondition: returns concatenation of lhs with rhs
{
apstring result(lhs); // copies lhs to result
result += rhs; // catenate rhs
return result; // returns a copy of result
}
apstring operator + ( char ch, const apstring & str )
// postcondition: returns concatenation of ch with str
{
apstring result; // make string equivalent of ch
result = ch;
result += str;
return result;
}
apstring operator + ( const apstring & str, char ch )
// postcondition: returns concatenation of str with ch
{
apstring result(str);
result += ch;
return result;
}
apstring apstring::substr(int
评论0