This repository was archived by the owner on Mar 21, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapstring.cpp
More file actions
359 lines (312 loc) · 10.5 KB
/
apstring.cpp
File metadata and controls
359 lines (312 loc) · 10.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
// *******************************************************************
// Last Revised: January 13, 1998, <= and >= redefined using ! and <
// operator += now takes constant
// amortized time for adding one char
//
// 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 "apstring.h"
const int npos = -1;
const int MAX_LENGTH = 1024; // largest size string for input
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;
assert(0 <= k && k < myLength);
}
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;
assert(0 <= k && k < myLength);
}
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 buf[MAX_LENGTH];
is >> buf;
str = buf;
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 buf[MAX_LENGTH];
is.getline(buf,MAX_LENGTH);
str = buf;
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 pos, int len) const
//description: extract and return the substring of length len starting
// at index pos
//precondition: this string represents c0, c1, ..., c(n-1)
// 0 <= pos <= pos + len - 1 < n.
//postcondition: returns the string that represents
// c(pos), c(pos+1), ..., c(pos+len-1)
//
{
if (pos < 0) // start at front when pos < 0
{
pos = 0;
}
if (pos >= myLength) return ""; // empty string
int lastIndex = pos + len - 1; // last char's index (to copy)
if (lastIndex >= myLength) // off end of string?
{
lastIndex = myLength-1;
}
apstring result(*this); // make sure enough space allocated
int j,k;
for(j=0,k=pos; k <= lastIndex; j++,k++)
{
result.myCstring[j] = myCstring[k];
}
result.myCstring[j] = '\0'; // properly terminate C-string
result.myLength = j; // record length properly
return result;
}
int apstring::find(const apstring & str) const
//description: find the first occurrence of the string str within this
// string and return the index of the first character. If
// str does not occur in this string, then return npos.
//precondition: this string represents c0, c1, ..., c(n-1)
// str represents s0, s1, ...,s(m-1)
//postcondition: if s0 == ck0, s1 == ck1, ..., s(m-1) == ck(m-1) and
// there is no j < k0 such that s0 = cj, ...., sm == c(j+m-1),
// then returns k0;
// otherwise returns npos
{
int len = str.length();
int lastIndex = length() - len;
int k;
for(k=0; k <= lastIndex; k++)
{
if (strncmp(myCstring + k,str.c_str(),len) == 0) return k;
}
return npos;
}
int apstring::find( char ch ) const
// description: finds the first occurrence of the character ch within this
// string and returns the index. If ch does not occur in this
// string, then returns npos.
// precondition: this string represents c0, c1, ..., c(n-1)
// postcondition: if ch == ck, and there is no j < k such that ch == cj
// then returns k;
// otherwise returns npos
{
int k;
for(k=0; k < myLength; k++)
{
if (myCstring[k] == ch)
{
return k;
}
}
return npos;
}
bool operator == ( const apstring & lhs, const apstring & rhs )
{
return strcmp(lhs.c_str(), rhs.c_str()) == 0;
}
bool operator != ( const apstring & lhs, const apstring & rhs )
{
return ! (lhs == rhs);
}
bool operator < ( const apstring & lhs, const apstring & rhs )
{
return strcmp(lhs.c_str(), rhs.c_str()) < 0;
}
bool operator <= ( const apstring & lhs, const apstring & rhs )
{
return !( rhs < lhs );
}
bool operator > ( const apstring & lhs, const apstring & rhs )
{
return rhs < lhs;
}
bool operator >= ( const apstring & lhs, const apstring & rhs )
{
return ! ( lhs < rhs );
}