Extremely Frustrated. Need help with custom substring class.

I'm working within the insert function in the substring.cpp file. I have to decide what to do if the insertion occurs exactly at the beginning or the ending of the substring. I don't understand what would make sense, and I'm not sure I understand my professor's diagram. Any help would be greatly appreciated. My thoughts are running in circles.

substring.cpp
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
// CIS-62 substring implementation

#include "substring.h"
#include <cctype>
#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();
    }
    if (pos > m_begin && pos < m_end){
        m_end += str.length();
    }
    if (pos == m_begin){
        m_end += str.length();
        //assuming the user wants the inserted string to be the beginning
        m_begin -= str.length();
    }
    if (pos == m_end){
        //assuming the user wants the inserted string to be the end
        m_end += str.length();
    }
    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()
{
    return *this;
}

// Convert substring to lower case
substring& substring::tolower()
{
    return *this;
}

// Search for a new substring starting at the specified position:
size_t substring::search( const std::string& str, size_t pos )
{
    return std::string::npos;
}

// The string content is set to the size of entire string
void substring::expand()
{
}

// Equality test between two substrings
bool substring::equals_to( substring const& other ) const
{
    return false;
}

// Equality test between substring and std::string
bool substring::equals_to( std::string const& str ) const
{
    return false;
}

// Merge with another substring
substring& substring::merge( substring const& other )
{
    return *this;
}

// Swap values with another substring
void substring::swap( substring& other )
{
    return *this;
}

// Test if substring is alphabetic
substring& substring::isalpha()
{
    return *this;
}

// Test if substring is upper case
substring& substring::isupper()
{
    return *this;
}

// Test if substring is lower case
substring& substring::islower()
{
    return *this;
}

// Test if substring is digit
substring& substring::isdigit()
{
    return *this;
}

// Test if substring is alphabetic or digit
substring& substring::isalnum()
{
    return *this;
}

// Test if substring is blank, tab, newline, return, formfeed, or vertical tab
substring& substring::isspace()
{
    return *this;
}

// Test if substring is matches text specified by str
substring& substring::isstr( const std::string& str )
{
    return *this;
}

// Test if substring is empty
substring& substring::isempty()
{
    return *this;
}

// Return true if parsing succeeded, false otherwise
bool substring::succeeded() const
{
    return false;
}

// Return matched substring
substring substring::match() const
{
    return *this;
}

// Undo changes caused by parsing
substring& substring::unparse()
{
    return *this;
}
Last edited on
substring.h
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
// CIS-62 substring class

#ifndef _CIS62_SUBSTRING_H_INCLUDED_
#define _CIS62_SUBSTRING_H_INCLUDED_

#include <string>

class substring {
    std::string& m_str;
    size_t m_begin;  // absolute offset of the substring beginning
    size_t m_end;    // absolute offset of the substring ending
public:
    // Constructor that takes a reference to a string:
    substring( std::string& str );

    // Constructor that takes string reference, beginning, and ending positions
    substring( std::string& str, size_t pos_begin, size_t pos_end );

    // Return copy of the substring as std::string object
    std::string str() const;

    // Return substring size
    size_t size() const;

    // Return beginning position
    size_t begin() const;

    // Return ending position
    size_t end() const;

    // Set beginning position
    void begin( size_t pos );

    // Set ending position
    void end( size_t pos );

    // The string content is set to an empty string
    void clear();

    // Replace substring with str
    substring& replace( std::string const& str );

    // Fill substring with a particular character
    substring& fill( char ch );

    // Insert str at the specified position:
    substring& insert( std::string const& str, size_t pos );

    // Convert substring to UPPER CASE
    substring& toupper();

    // Convert substring to lower case
    substring& tolower();

    // Search for a new substring starting at the specified position:
    size_t search( const std::string& str, size_t pos );

    // The string content is set to the size of entire string
    void expand();

    // Equality test between two substrings
    bool equals_to( substring const& other ) const;

    // Equality test between substring and std::string
    bool equals_to( std::string const& str ) const;

    // Merge with another substring
    substring& merge( substring const& other );

    // Swap with another substring
    void swap( substring& other );

    // Prepare substring for parsing
    substring& parse();

    // Test if substring is alphabetic
    substring& isalpha();

    // Test if substring is upper case
    substring& isupper();

    // Test if substring is lower case
    substring& islower();

    // Test if substring is digit
    substring& isdigit();

    // Test if substring is alphabetic or digit
    substring& isalnum();

    // Test if substring is blank, tab, newline, return, formfeed, or vertical tab
    substring& isspace();

    // Test if substring is matches text specified by str
    substring& isstr( const std::string& str );

    // Test if substring is empty
    substring& isempty();

    // Return beginning position
    bool succeeded() const;

    // Return matching substring
    substring match() const;

    // Undo changes caused by parsing
    substring& unparse();
};

#endif // _CIS62_SUBSTRING_H_INCLUDED_ 


substring_main.cpp
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
// main driver sample to test substring functionality.

#include <cassert>
#include <iostream>
#include "substring.h"

int main()
{
    //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
    // Test basic substring functionality
    //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
    std::string str( "abc" );
    substring sub( str );

    std::cout << '\n' << sub.str() << '\n';//DEBUG

    assert( sub.str() == "abc" );
    assert( sub.begin() == 0 );
    assert( sub.end() == 3 );
    assert( sub.end() == sub.size() );

    sub.begin( 1 ); // reposition absolute offsets
    sub.end( 2 );
    assert( sub.str() == "b" );

    std::cout << '\n' << sub.str() << '\n';//DEBUG

    sub.replace( "HELLO" );
    assert( sub.str() == "HELLO" );
    assert( str == "aHELLOc" );
    assert( sub.begin() == 1 );
    assert( sub.end() == 6 );
    assert( sub.size() == 5 );

    sub.clear();
    assert( sub.str() == "" );
    assert( str == "ac" );
    assert( sub.begin() == 1 );
    assert( sub.end() == 1 );
    assert( sub.size() == 0 );

    sub.insert( "XYZ", sub.begin() );
    assert( str == "aXYZc" );

    sub.expand();
    assert( str == "aXYZc" );
    assert( sub.begin() == 0 );
    assert( sub.end() == str.size() );

    size_t result = sub.search( "YZc", sub.end() );
    assert( result == std::string::npos );

    result = sub.search( "YZc", sub.begin() );
    assert( result == 2 );
    assert( sub.begin() == 2 );
    assert( sub.end() == str.size() );
    assert( sub.size() == 3 );

    sub.fill( '?' );
    assert( sub.begin() == 2 );
    assert( sub.end() == str.size() );
    assert( sub.equals_to( "???" ) );
    assert( str == "aX???" );

    sub.expand();
    sub.toupper();
    assert( sub.equals_to( "AX???" ) );
    assert( str == "AX???" );

    sub.tolower();
    assert( sub.equals_to( "ax???" ) );
    assert( str == "ax???" );

    substring sub2 = sub; // invokes copy constructor
    result = sub2.search( "x?", sub.begin() );
    assert( sub2.equals_to( "x?" ) );
    assert( sub.equals_to( "ax???" ) );

    sub2.merge( sub );
    assert( sub2.equals_to( "ax???" ) );
    assert( sub.equals_to( sub2 ) );

    //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
    // Parsing tests
    //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
    str = "ABC123abc ";
    sub.expand();
    if ( sub.parse().isalpha().isdigit().isalnum().isspace().isempty().succeeded() ) {
        sub.match().replace( "xyz" );
        assert( str == "xyz" );
    } else {
        sub.unparse(); // restore the original substring
    }

    return 0;
}
Topic archived. No new replies allowed.