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
|
#include "substring.h"
#include <string>
#include <iostream>
// Constructor that takes a reference to a string:
substring::substring( std::string& str )
:
m_str(str),
m_begin(0),
m_end(str.length())
{
/*
The substring class is entirely dependent on the std::string object
which has to be passed to each constructor. It will be refferred to
as "underlying string object" in our comments.
DONE: Add initializer list to this constructor, or your code won't
compile.
DONE: Add two member variables to accommodate the substring
positions,
size_t m_begin; // absolute offset of the substring beginning
size_t m_end; // absolute offset of the substring ending
and set these positions to match the entire string.
*/
}
// Constructor that takes string reference, beginning, and ending positions
substring::substring( std::string& str, size_t pos_begin, size_t pos_end )
:
m_str(str),
m_begin(pos_begin),
m_end(pos_end)
{
/*
In addition to std::string object, this constructor
takes two absolute positions to initialize m_begin
and m_end offsets of the substring object.
DONE: Add initializer list to this constructor, or your code won't
compile.
*/
}
// Return copy of the substring as std::string object
std::string substring::str() const
{
/*
This function returns a copy of the string object, initialized
by the characters of the substring.
DONE: modify the following statement to construct and return
the appropriate string:
*/
return m_str.substr(m_begin, size());
// starting length
// position
}
// Return substring size
size_t substring::size() const
{
return m_end - m_begin;
}
// Return beginning position
size_t substring::begin() const
{
return m_begin;
}
// Return ending position
size_t substring::end() const
{
return m_end;
}
// Set beginning position
void substring::begin( size_t pos )
{
m_begin = pos;
}
// Set ending position
void substring::end( size_t pos )
{
m_end = pos;
}
// The string content is set to an empty string
void substring::clear()
{
m_str.replace(m_begin, size(), "");
m_end = m_begin;
}
// Replace substring with str
substring& substring::replace( std::string const& str )
{
m_str.replace(m_begin, size(), str);
m_end = m_begin + str.length();
return *this;
}
// Fill substring with a particular character
substring& substring::fill( char ch )
{
size_t pos = m_begin;
for(; pos < m_end; ++pos){
m_str[pos] = ch;
}
return *this;
}
// Insert str at the specified position:
substring& substring::insert( std::string const& str, size_t pos )
{
/*
Hint: use insert() member function of std::string.
TODO: because insert causes changes in the underlying substring,
the function must compare its beginning and ending against the
insertion position and the length of the string being inserted.
The substring needs to adjust its beginning and ending positions
as demonstrated by the following diagrams:
Example 1.
BEFORE insert:
insert( "abc", pos )
|
.--'
|
m_str: XXXX?????????????????XXXXXXXXXX
| |
'-m_begin `-m_end
AFTER insert:
|
m_str: XXabcXX?????????????????XXXXXXXXXX
| |
'-m_begin: `-m_end:
got adjusted got adjusted
Example 2.
BEFORE insert:
insert( "abc", pos )
|
`-------.
|
m_str: XXXX?????????????????XXXXXXXXXX
| |
'-m_begin `-m_end
AFTER insert:
|
m_str: XXXX?????????abc???????XXXXXXXXXX
| |
'-m_begin `-m_end: got adjusted
IMPORTANT: Make your own decision regarding two special cases
when the insertion occurs exactly at the beginning, or exactly
at the ending of the substring. Make sure to document your
coding in the comments of your program.
*/
std::cout << "end pos: " << m_end << '\n';//debug
std::cout << "beg pos: " << m_begin << '\n';//debug
m_str.insert(pos, str);
if (pos < m_begin){
m_begin += str.length();
m_end += str.length();
std::cout << "pos < m_begin \n";//db
}
else if (pos > m_begin && pos < m_end){
m_end += str.length();
std::cout << "pos > m_begin AND < m_end \n";//db
}
else if (pos == m_begin){
m_end += str.length();
//assuming the user wants the inserted string to be the beginning
std::cout << "pos == m_begin \n";//db
}
else if (pos == m_end){
//assuming the user wants the inserted string to be the end
m_end += str.length();
std::cout << "pos == m_end \n";//db
}
std::cout << "end pos: " << m_end << '\n';//debug
std::cout << "beg pos: " << m_begin << '\n';//debug
return *this;
}
// Convert substring to UPPER CASE
substring& substring::toupper()
{
size_t pos = m_begin;
for(; pos < m_end; ++pos){
m_str[pos] = std::toupper(m_str[pos]);
}
return *this;
}
// Convert substring to lower case
substring& substring::tolower()
{
size_t pos = m_begin;
for(; pos < m_end; ++pos){
m_str[pos] = std::tolower(m_str[pos]);
}
return *this;
}
// Search for a new substring starting at the specified position:
size_t substring::search( const std::string& str, size_t pos )
{
/*
DONE: use find() of the underlying string and update the beginning
and the ending positions of the substring.
DONE: when find() call fails, it returns back the member value
std::string::npos. In such case the substring must not update
its positions and also return std::string::npos back to the caller:
*/
size_t result = result = m_str.find(str, pos);
if (result != std::string::npos){
m_begin = result;
m_end = m_begin + str.length();
return result;
}
else{
return std::string::npos;
}
}
// The string content is set to the size of entire string
void substring::expand()
{
/*
DONE: Update substring positions to match the entire
underlying string.
*/
m_begin = 0;
m_end = m_str.length();
}
// Equality test between two substrings
bool substring::equals_to( substring const& other ) const
{
/*
TODO: Compare this substring with another character by character.
The test should succeed if every character in both substrings
matches exactly.
Return true, if the underlying text fragments are the same.
Return false otherwise.
*/
size_t pos = m_begin;
return false;
}
|