Need help with assignment

Pages: 12
I'm working on an assignment and am very new to a lot of the concepts it wants me to do.

I have not finished the code yet. As of now I simply want to see if my code looks correct. Below is my assignment is below that is my current code.

I haven't yet gotten to member function 2, so you don't have to read there and beyond yet. All I've done is added the names to the header.

~~~

Instructions: In this lab you will create a class for a Dynamic Array of Strings. This class may be useful for future projects. The class will provide the following functionality:

Get a string from the array

Add a string to the front or back of the array

Delete a string from the front or back of the array

Get the number of strings in the array

Get the maximum capacity of the array

Clear the array

Sort the array

Get the array as a comma separated list

Ability to grow on demand

For Extra Credit you can add the following:

Save the array to a file

Retrieve a previous saved array from a file

Class –DynamicStringArray:
Contains a dynamic array of dynamic strings.

Private Data Members:
A dynamic array of dynamic strings, i.e. a dynamic array of string*s.
An integer to hold the maximum capacity of your array.
An integer to hold the current size of your array.

Default Constructor:
Initializes the array to 10 elements and initializes the elements to NULL.

Overloaded Constructor:
Initializes the array via an unsigned integer parameter. If the parameter's valueis not valid (i.e. 0) set the array to a capacity of 10. Initializes all elements to NULL.

Destructor:
Frees the memory for all strings
Frees the memory for the dynamic string* array

Member Function 1:
Named At. Has one parameter, anunsigned integer that corresponds to a location in the array. If that location doesn't exist in the array throw the string "Invalid Location". If the location does exist return a pointer to the string.

Member Function 2:
Named GetFirst. Returns a pointer to the first string in the array. If the array is empty throw the string "Array Empty".

Member Function 3:
Named GetLast. Returns a pointer to the first string in the array. If the array is empty throw
the string "Array Empty".

Member Function 4:
Named AddFront. Has one parameter, a dynamic string. Adds this string to the beginning of the array. Note: this requires you to shift all the elements in the array. If the array is full increase the capacity of the array (call the IncreaseCapacityfunction) and then add the dynamic string.

Member Function 5:
Named AddBack. Has one parameter, a dynamic string. Adds this string to the end of the array. If the array is full increase the capacity of the array (call the IncreaseCapacityfunction) and then add the dynamic string.

Member Function 6:
Named DeleteFront. Deletes the first element in the array. Note: this requires you to shift all the elements in the array. If the array is empty throw the string "Array Empty".

Member Function 7:
Named DeleteBack. Deletes the last element in the array. If the array is empty throw the string "Array Empty".

Member Function 8:
Named GetSize. Returns an unsigned integer that is the current size of the array. This is a const function.

Member Function 9:
Named GetCapacity. Returns an unsigned integer that is the current maximum capacity of the array. This is a const function.

Member Function 10:
Named Empty. Returns a Boolean. True if the array's size is 0. This is a const function.

Member Function 11:
Named Clear. Deletes all of the dynamic strings in the array and sets the size of the array to 0.

Member Function 12:
Named Sort. Sorts the array A-Z. You must use the private function ToUpper as this helps when comparing strings of mixed case.

Member Function 13:
Named ToString. Returns a string containing all of the strings in
the array, comma separated.

Overloaded Friend operator<<:

Outputs a comma separated list of all of the strings in the array.

Private Member Function 1:
Named IncreaseCapacity. Increases the capacity of the array by 10. Note: this requires you making a second dynamic array and "copying" over the original data.

Private Member Function 2:
Named ToUpper. Takes a string as a parameter and returns that
same string with all the characters uppercased.
Last edited on
This is my code so far:

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
#include "dynamic_string_array.h"
#include <iostream>
#include <cmath>
#include <string>
#include <cctype>
#include <sstream>
using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::stringstream;

DynamicStringArray::DynamicStringArray() {
  myarray = new char*[defaultincrease];
  arraysize = defaultincrease;
}

DynamicStringArray::DynamicStringArray(int arraymax = 10) {
  arraysize = arraymax;
  int *myarray[arraymax] = {};
}

DynamicStringArray::~DynamicStringArray() {
  delete[] arraysize_;
}

char * DynamicStringArray::At(const unsigned int i) {
  if((i < 0) || (i > myarray) {
    throw "Invalid Location";
  }
  return string* myarray->at(i);
}


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
#ifndef DYNAMIC_STRING_ARRAY_H
#define DYNAMIC_STRING_ARRAY_H
#include <string>
#include <climits>

class DynamicStringArray {
private:
  char** myarray;
  static const int defaultincrease = 10;
  int arraysize;
  int IncreaseCapacity();
  string ToUpper();
public:
  DynamicStringArray();
  char* At(unsigned int loc);
  char* GetFirst();
  char* GetLast();
  void AddFront(string *str);
  void AddBack(string *str);
  void DeleteFront();
  void DeleteBack();
  int* GetSize();
  int* GetCapacity();
  bool Empty();
  void Clear();
  string* Sort();
  string* ToString();
}

#endif /* DYNAMIC_STRING_ARRAY_H */ 


Does this look correct so far?
In the destructor, you misspelled a variable name.
Memory allocated dynamically with new or new[] must be freed using delete or delete[] respectively. Look At what variable you assigned that memory, then look in your destructor. Do you see the error?

Also note that throw is a reserved keyword for throwing exceptions. Is this what the instructor wanted, or did he/she want member functions 6 and 7 to return specific strings in the event of an empty array?

Member functions 8 and 9 are required to be const functions and to return a value of type unsigned int. do the function declarations in your header file meet these requirements?
Last edited on
So sorry! My internet went out for awhile! I've made a lot of changes to my code since then, but I'm getting compiler errors.

This is my CPP file.

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
#include "dynamic_string_array.h"
#include <iostream>
#include <cmath>
#include <string>
#include <cctype>
#include <sstream>
using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::stringstream;

DynamicStringArray::DynamicStringArray() {
  int i = 0;
  std::string* myarray[10];
  while (i < 10) {
    myarray[i] = NULL;
    ++i;
  }
}

DynamicStringArray::DynamicStringArray(int size = 10) {
  int i = 0;
  arraysize = size;
  std::string* myarray[arraysize];
  while (i < arraysize) {
    myarray[i] = NULL;
    ++i;
  }
}

DynamicStringArray::~DynamicStringArray() {
  delete [] myarray;
  currentsize = 0;
}

std::string DynamicStringArray::At(int i) const {
  if(i > arraysize) {
    throw "Invalid Location";
  }
  return myarray[i];
}

std::string DynamicStringArray::GetFirst() {
  if(currentsize == 0) {
    throw "Array Empty";
  }
  return myarray[0];
}

std::string DynamicStringArray::GetLast() {
  int i = currentsize;
  if(currentsize == 0) {
    throw "Array Empty";
  }
  return myarray[i];
}

void DynamicStringArray::AddFront(std::string str) {
  if(currentsize == arraysize) {
    IncreaseCapacity();
  }
  for (int i = currentsize; i > 0; i--) {
    myarray[i] = myarray[i - 1];
  }
  myarray[0] = str;
  currentsize++;
}
 
void DynamicStringArray::AddBack(std::string str) {
  int i = currentsize;
  if(currentsize == arraysize) {
    IncreaseCapacity();
  }
  myarray[i + 1] = str;
  currentsize++;
}

void DynamicStringArray::DeleteFront() {
  if(currentsize == 0) {
    throw "Array Empty";
  }
  for (int i = 0; i < currentsize; i++) {
    myarray[i] = myarray[i + 1];
  }
  currentsize--;
}

void DynamicStringArray::DeleteBack() {
  int i = currentsize;
  if(currentsize == 0) {
    throw "Array Empty";
  }
  myarray[i] = NULL;
  currentsize--;
}

unsigned DynamicStringArray::GetSize() const {
  unsigned int size = currentsize;
  return size;
}

unsigned DynamicStringArray::GetCapacity() const {
  unsigned int size = arraysize;
  return size;
}

bool DynamicStringArray::Empty() const {
  bool empty;
  if(currentsize == 0) {
    empty = true;
  } else {
    empty = false;
  }
  return empty;
}

void DynamicStringArray::Clear() {
  delete [] myarray;
  currentsize = 0;
}
 
void DynamicStringArray::Sort() {
  int i;
  int j;
  for (i = 0; i <= (currentsize - 1); i++) {
    j = i;
    while ((j > 0) && (myarray[j] < myarray[j - 1])) {
      std::swap(myarray[j], myarray[j - 1]);
      j = j - 1;
    }
  }
}

std::string DynamicStringArray::ToString() {
  std::stringstream ss;
  ss << *this;
  return ss.str();
}

std::ostream& operator<<(std::ostream&, const DynamicStringArray&) {
  for (int i = 0; i < currentsize - 1; i++) {
    (myarray[i])->push_back(',');
  }
  return myarray;
}

void DynamicStringArray::IncreaseCapacity() {
   const int oldsize = arraysize;
   arraysize += 10;
   std::string* newarray = new std::string[arraysize];
   for (int i = 0; i < oldsize; i++) {
      newarray[i] = myarray[i];
   }
   delete [] myarray;
   myarray = NULL;
   std::swap(myarray, newarray);
}

std::string DynamicStringArray::ToUpper(std::string letter) {
  for (unsigned int i = 0; i < letter.length(); i++) {
    letter.at(i) = toupper(letter.at(i));    
  }
  return letter;
}


This is my header:

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
#ifndef DYNAMIC_STRING_ARRAY_H
#define DYNAMIC_STRING_ARRAY_H
#include <string>
#include <climits>

class DynamicStringArray {
public:
  DynamicStringArray();
  DynamicStringArray(int);
  ~DynamicStringArray();
  std::string At(int i) const;
  std::string GetFirst();
  std::string GetLast();
  void AddFront(std::string str);
  void AddBack(std::string str);
  void DeleteFront();
  void DeleteBack();
  unsigned GetSize() const;
  unsigned GetCapacity() const;
  bool Empty() const;
  void Clear();
  void Sort();
  std::string ToString(); 
  friend std::ostream& operator<<(std::ostream&, const DynamicStringArray&);
private:
  std::string * myarray;
  int arraysize;
  int currentsize;
  void IncreaseCapacity(); 
  std::string ToUpper(std::string letter);
};

#endif /* DYNAMIC_STRING_ARRAY_H */ 


And this is my current compiler error:

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
dynamic_string_array.cpp: In constructor ‘DynamicStringArray::DynamicStringArray()’:
dynamic_string_array.cpp:21:16: warning: variable ‘myarray’ set but not used [-Wunused-but-set-variable]
   std::string* myarray[10];
                ^
dynamic_string_array.cpp: In constructor ‘DynamicStringArray::DynamicStringArray(int)’:
dynamic_string_array.cpp:31:16: warning: variable ‘myarray’ set but not used [-Wunused-but-set-variable]
   std::string* myarray[arraysize];
                ^
dynamic_string_array.cpp: In member function ‘void DynamicStringArray::DeleteBack()’:
dynamic_string_array.cpp:100:14: error: ambiguous overload foroperator=’ (operand types are ‘std::string {aka std::basic_string<char>}’ and ‘long int’)
   myarray[i] = NULL;
              ^
dynamic_string_array.cpp:100:14: note: candidates are:
In file included from /usr/lib/gcc/x86_64-pc-cygwin/4.9.2/include/c++/string:52:0,
                 from dynamic_string_array.h:9,
                 from dynamic_string_array.cpp:7:
/usr/lib/gcc/x86_64-pc-cygwin/4.9.2/include/c++/bits/basic_string.h:554:7: note: std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::operator=(const std::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
       operator=(const basic_string& __str)
       ^
/usr/lib/gcc/x86_64-pc-cygwin/4.9.2/include/c++/bits/basic_string.h:562:7: note: std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::operator=(const _CharT*) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
       operator=(const _CharT* __s)
       ^
/usr/lib/gcc/x86_64-pc-cygwin/4.9.2/include/c++/bits/basic_string.h:573:7: note: std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::operator=(_CharT) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
       operator=(_CharT __c)
       ^
dynamic_string_array.cpp: In function ‘std::ostream& operator<<(std::ostream&, const DynamicStringArray&)’:
dynamic_string_array.cpp:148:23: error: ‘currentsize’ was not declared in this scope
   for (int i = 0; i < currentsize - 1; i++) {
                       ^
dynamic_string_array.cpp:149:6: error: ‘myarray’ was not declared in this scope
     (myarray[i])->push_back(',');
      ^
dynamic_string_array.cpp:151:10: error: ‘myarray’ was not declared in this scope
   return myarray;
          ^
dynamic_string_array.cpp:152:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
makefile:10: recipe for target 'dynamic_string_array' failed
make: *** [dynamic_string_array] Error 1


I'm very lost as to why this isn't working. Could someone help me, please?
Last edited on
Bump
dynamic_string_array.cpp: In member function ‘void DynamicStringArray::DeleteBack()’:
dynamic_string_array.cpp:100:14: error: ambiguous overload for ‘operator=’ (operand types are ‘std::string {aka std::basic_string<char>}’ and ‘long int’)
myarray[i] = NULL;

You need to change myarray[i] = NULL; to myarray[i] = "";, or leave that out. It's not considered part of your array anymore, so the user can't access it anyway.


dynamic_string_array.cpp: In function ‘std::ostream& operator<<(std::ostream&, const DynamicStringArray&)’:
dynamic_string_array.cpp:148:23: error: ‘currentsize’ was not declared in this scope
for (int i = 0; i < currentsize - 1; i++) {

The function is not part of your DynamicStringArray class. currentsize is not part of the std::ostream class.


dynamic_string_array.cpp:149:6: error: ‘myarray’ was not declared in this scope
(myarray[i])->push_back(',');

Same as above.


dynamic_string_array.cpp:151:10: error: ‘myarray’ was not declared in this scope
return myarray;

Same as above.


dynamic_string_array.cpp:152:1: warning: control reaches end of non-void function [-Wreturn-type]
}

The function is supposed to be returning something of type std::ostream&, but you have not done so.
Last edited on
So for the friend operator, would I put in "DynamicStringArray::myarray" instead to access it?
Last edited on
No, you wouldn't. Honestly, I can't make any sense of your function.

1
2
3
4
5
6
std::ostream& operator<<(std::ostream&, const DynamicStringArray&) {
  for (int i = 0; i < currentsize - 1; i++) {
    (myarray[i])->push_back(',');
  }
  return myarray;
}


1. You didn't provide any name for your DynamicStringArray& parameter. Assuming you gave it the name DSA, since this is a friend function you can access its elements like so: DSA.currentsize.

2. The const in front of it means that you're not allowed to change anything to the DynamicStringArray, which appears to be what you're trying to do in your loop.

3. The contents of your function has nothing to do with ostream, so I don't know why you have ostream parameters and return type in the first place.

4. myarray[i] would be a string, not a pointer to a string, so you wouldn't use the -> operator.
Last edited on
OK, to make sure I'm understanding...

2) Delete const.

3) Delete std::ostream&.

4) Remove ->. But what would I put in its place?
3) Delete std::ostream&.

That really depends on what you want to do with the function.

std::ostream& operator<<(std::ostream&, const DynamicStringArray&)

^This means that you're trying to overload the output operator (<<) but you're not doing any output operations. The only thing I can tell is that you're adding commas to the end of every string (except the last one).

If that's all it's supposed to do, then yes, you should get rid of all the ostream stuff. In fact, you should change it to be one of your class's member functions instead of an operator overload function.

Otherwise, if you're really trying to overload the << operator, then you should keep all the ostream stuff and have your function actually output something.

4) Remove ->. But what would I put in its place?
push_back is a function of string, so you'd use myarray[i].push_back(',');
Well this is what the assignment calls for

Overloaded Friend operator<<:

Outputs a comma separated list of all of the strings in the array.


Seeing that it's called an "overloaded operator", I guess I am trying to overload it. But how exactly would I "output something" in this case? Also I changed the codes a little bit, but I'm still getting some errors:

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
#include "dynamic_string_array.h"
#include <iostream>
#include <cmath>
#include <string>
#include <cctype>
#include <sstream>
using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::stringstream;

DynamicStringArray::DynamicStringArray() {
  int i = 0;
  std::string* myarray[10];
  while (i < 10) {
    myarray[i] = "";
    ++i;
  }
}

DynamicStringArray::DynamicStringArray(int size = 10) {
  int i = 0;
  arraysize = size;
  std::string* myarray[arraysize];
  while (i < arraysize) {
    myarray[i] = "";
    ++i;
  }
}

DynamicStringArray::~DynamicStringArray() {
  delete [] myarray;
  currentsize = 0;
}

std::string DynamicStringArray::At(int i) const {
  if(i > arraysize) {
    throw "Invalid Location";
  }
  return myarray[i];
}

std::string DynamicStringArray::GetFirst() {
  if(currentsize == 0) {
    throw "Array Empty";
  }
  return myarray[0];
}

std::string DynamicStringArray::GetLast() {
  int i = currentsize;
  if(currentsize == 0) {
    throw "Array Empty";
  }
  return myarray[i];
}

void DynamicStringArray::AddFront(std::string str) {
  if(currentsize == arraysize) {
    IncreaseCapacity();
  }
  for (int i = currentsize; i > 0; i--) {
    myarray[i] = myarray[i - 1];
  }
  myarray[0] = str;
  currentsize++;
}
 
void DynamicStringArray::AddBack(std::string str) {
  int i = currentsize;
  if(currentsize == arraysize) {
    IncreaseCapacity();
  }
  myarray[i + 1] = str;
  currentsize++;
}

void DynamicStringArray::DeleteFront() {
  if(currentsize == 0) {
    throw "Array Empty";
  }
  for (int i = 0; i < currentsize; i++) {
    myarray[i] = myarray[i + 1];
  }
  currentsize--;
}

void DynamicStringArray::DeleteBack() {
  int i = currentsize;
  if(currentsize == 0) {
    throw "Array Empty";
  }
  myarray[i] = "";
  currentsize--;
}

unsigned DynamicStringArray::GetSize() const {
  unsigned int size = currentsize;
  return size;
}

unsigned DynamicStringArray::GetCapacity() const {
  unsigned int size = arraysize;
  return size;
}

bool DynamicStringArray::Empty() const {
  bool empty;
  if(currentsize == 0) {
    empty = true;
  } else {
    empty = false;
  }
  return empty;
}

void DynamicStringArray::Clear() {
  delete [] myarray;
  currentsize = 0;
}
 
void DynamicStringArray::Sort() {
  int i;
  int j;
  for (i = 0; i <= (currentsize - 1); i++) {
    j = i;
    while ((j > 0) && (myarray[j] < myarray[j - 1])) {
      std::swap(myarray[j], myarray[j - 1]);
      j = j - 1;
    }
  }
}

std::string DynamicStringArray::ToString() {
  std::stringstream ss;
  ss << *this;
  return ss.str();
}

std::ostream& operator<<(std::ostream&, DynamicStringArray&) {
  for (int i = 0; i < DSA.currentsize - 1; i++) {
    (DSA.myarray[i].push_back(',');
  }
  return DSA.myarray;
}

void DynamicStringArray::IncreaseCapacity() {
   const int oldsize = arraysize;
   arraysize += 10;
   std::string* newarray = new std::string[arraysize];
   for (int i = 0; i < oldsize; i++) {
      newarray[i] = myarray[i];
   }
   delete [] myarray;
   myarray = NULL;
   std::swap(myarray, newarray);
}

std::string DynamicStringArray::ToUpper(std::string letter) {
  for (unsigned int i = 0; i < letter.length(); i++) {
    letter.at(i) = toupper(letter.at(i));    
  }
  return letter;
}


Header:

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
#ifndef DYNAMIC_STRING_ARRAY_H
#define DYNAMIC_STRING_ARRAY_H
#include <string>
#include <climits>

class DynamicStringArray {
public:
  DynamicStringArray();
  DynamicStringArray(int);
  ~DynamicStringArray();
  std::string At(int i) const;
  std::string GetFirst();
  std::string GetLast();
  void AddFront(std::string str);
  void AddBack(std::string str);
  void DeleteFront();
  void DeleteBack();
  unsigned GetSize() const;
  unsigned GetCapacity() const;
  bool Empty() const;
  void Clear();
  void Sort();
  std::string ToString(); 
  friend std::ostream& operator<<(std::ostream&, const DynamicStringArray&);
private:
  std::string * myarray;
  int arraysize;
  int currentsize;
  std::string* DSA;
  void IncreaseCapacity(); 
  std::string ToUpper(std::string letter);
};

#endif /* DYNAMIC_STRING_ARRAY_H */ 


Compiler Error:

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
$ make
/usr/bin/g++ -Wall -Wextra -g dynamic_string_array.cpp  -o dynamic_string_array
dynamic_string_array.cpp: In constructor ‘DynamicStringArray::DynamicStringArray()’:
dynamic_string_array.cpp:23:16: error: cannot convert ‘const char [1]’ to ‘std::string* {aka std::basic_string<char>*}’ in assignment
     myarray[i] = "";
                ^
dynamic_string_array.cpp: In constructor ‘DynamicStringArray::DynamicStringArray(int)’:
dynamic_string_array.cpp:33:16: error: cannot convert ‘const char [1]’ to ‘std::string* {aka std::basic_string<char>*}’ in assignment
     myarray[i] = "";
                ^
dynamic_string_array.cpp: In function ‘std::ostream& operator<<(std::ostream&, DynamicStringArray&)’:
dynamic_string_array.cpp:148:23: error: ‘DSA’ was not declared in this scope
   for (int i = 0; i < DSA.currentsize - 1; i++) {
                       ^
dynamic_string_array.cpp:149:35: error: expected ‘)’ before ‘;’ token
     (DSA.myarray[i].push_back(',');
                                   ^
dynamic_string_array.cpp:151:10: error: ‘DSA’ was not declared in this scope
   return DSA.myarray;
          ^
dynamic_string_array.cpp:152:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
makefile:10: recipe for target 'dynamic_string_array' failed
make: *** [dynamic_string_array] Error 1


So with DSA, so I also need to declare it somewhere in the friend operator?
Last edited on
When I gave an example of DSA, I didn't mean for you to add it as a member of your class. I meant that it's something you could name your parameter.

1
2
3
4
5
6
std::ostream& operator<<(std::ostream&, DynamicStringArray&) {
  for (int i = 0; i < DSA.currentsize - 1; i++) {
    (DSA.myarray[i].push_back(',');
  }
  return DSA.myarray;
}

^See right there? You named neither your std::ostream& nor DynamicStringArray& parameters.

1
2
3
4
5
6
std::string DynamicStringArray::ToUpper(std::string letter) {
  for (unsigned int i = 0; i < letter.length(); i++) {
    letter.at(i) = toupper(letter.at(i));    
  }
  return letter;
}

^See right there? In this case, you did name your parameter. You named the string letter.

/usr/bin/g++ -Wall -Wextra -g dynamic_string_array.cpp -o dynamic_string_array
dynamic_string_array.cpp: In constructor ‘DynamicStringArray::DynamicStringArray()’:
dynamic_string_array.cpp:23:16: error: cannot convert ‘const char [1]’ to ‘std::string* {aka std::basic_string<char>*}’ in assignment
myarray[i] = "";
^
dynamic_string_array.cpp: In constructor ‘DynamicStringArray::DynamicStringArray(int)’:
dynamic_string_array.cpp:33:16: error: cannot convert ‘const char [1]’ to ‘std::string* {aka std::basic_string<char>*}’ in assignment
myarray[i] = "";

^This is because your constructors are wrong. Why are you creating an array of string pointers named myarray?

std::string* myarray[10];

You're supposed to be allocating memory for your class member, myarray.

1
2
3
4
5
6
7
private:
  std::string * myarray;
  int arraysize;
  int currentsize;
  std::string* DSA;
  void IncreaseCapacity(); 
  std::string ToUpper(std::string letter);
Last edited on
Ahhh OK, so the DynamicStringArray& parameter is to reference the DynamicStringArray class. But what do I do with the std::ostream& parameter once I have named it?

As for myarray, in the constructor I am supposed to set all elements to NULL. How would I do that in this case?
But what do I do with the std::ostream& parameter once I have named it?


Then you could output stuff to it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
std::ostream& triple(std::ostream& out, std::string str)
{
    out << str << std::endl;
    out << str << std::endl;
    out << str << std::endl;
    return out;
}

int main()
{
    std::ofstream outfile("output.txt");
    triple(std::cout, "This is console output.");
    triple(outfile, "This is file output.");
    return 0;
}


As for myarray, in the constructor I am supposed to set all elements to NULL. How would I do that in this case?

Your loop already does that. You just have to make sure to get rid of

std::string* myarray[10];

and replace it with code for allocating memory for your array.
You mean like this?

myarray = new string[10];

Yes
OK, I have a new compile error and I have no clue what it means:

1
2
3
4
5
6
7
8
$ make
/usr/bin/g++ -Wall -Wextra -g dynamic_string_array.cpp  -o dynamic_string_array
/usr/lib/gcc/x86_64-pc-cygwin/4.9.2/../../../../lib/libcygwin.a(libcmain.o): In function `main':
/usr/src/debug/cygwin-1.7.33-1/winsup/cygwin/lib/libcmain.c:39: undefined reference to `WinMain'
/usr/src/debug/cygwin-1.7.33-1/winsup/cygwin/lib/libcmain.c:39:(.text.startup+0x7e): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `WinMain'
collect2: error: ld returned 1 exit status
makefile:10: recipe for target 'dynamic_string_array' failed
make: *** [dynamic_string_array] Error 1 


This is my current CPP and Header:

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
#include "dynamic_string_array.h"
#include <iostream>
#include <cmath>
#include <string>
#include <cctype>
#include <sstream>
using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::stringstream;

DynamicStringArray::DynamicStringArray() {
  int i = 0;
  myarray = new std::string[10];
  while (i < 10) {
    myarray[i] = "";
    ++i;
  }
}

DynamicStringArray::DynamicStringArray(int size) : arraysize(size), currentsize(0) {
  myarray = new std::string[arraysize];
}

DynamicStringArray::~DynamicStringArray() {
  delete [] myarray;
  currentsize = 0;
}

std::string DynamicStringArray::At(int i) const {
  if(i > arraysize) {
    throw "Invalid Location";
  }
  return myarray[i];
}

std::string DynamicStringArray::GetFirst() {
  if(currentsize == 0) {
    throw "Array Empty";
  }
  return myarray[0];
}

std::string DynamicStringArray::GetLast() {
  int i = currentsize;
  if(currentsize == 0) {
    throw "Array Empty";
  }
  return myarray[i];
}

void DynamicStringArray::AddFront(std::string str) {
  if(currentsize == arraysize) {
    IncreaseCapacity();
  }
  for (int i = currentsize; i > 0; i--) {
    myarray[i] = myarray[i - 1];
  }
  myarray[0] = str;
  currentsize++;
}
 
void DynamicStringArray::AddBack(std::string str) {
  int i = currentsize;
  if(currentsize == arraysize) {
    IncreaseCapacity();
  }
  myarray[i + 1] = str;
  currentsize++;
}

void DynamicStringArray::DeleteFront() {
  if(currentsize == 0) {
    throw "Array Empty";
  }
  for (int i = 0; i < currentsize; i++) {
    myarray[i] = myarray[i + 1];
  }
  currentsize--;
}

void DynamicStringArray::DeleteBack() {
  int i = currentsize;
  if(currentsize == 0) {
    throw "Array Empty";
  }
  myarray[i] = "";
  currentsize--;
}

unsigned DynamicStringArray::GetSize() const {
  unsigned int size = currentsize;
  return size;
}

unsigned DynamicStringArray::GetCapacity() const {
  unsigned int size = arraysize;
  return size;
}

bool DynamicStringArray::Empty() const {
  bool empty;
  if(currentsize == 0) {
    empty = true;
  } else {
    empty = false;
  }
  return empty;
}

void DynamicStringArray::Clear() {
  delete [] myarray;
  currentsize = 0;
}
 
void DynamicStringArray::Sort() {
  int i;
  int j;
  for (i = 0; i <= (currentsize - 1); i++) {
    j = i;
    while ((j > 0) && (myarray[j] < myarray[j - 1])) {
      std::swap(myarray[j], myarray[j - 1]);
      j = j - 1;
    }
  }
}

std::string DynamicStringArray::ToString() {
  std::stringstream ss;
  ss << *this;
  return ss.str();
}

std::ostream& operator<<(std::ostream& comma, const DynamicStringArray& DSA) {
  for (int i = 0; i < DSA.currentsize - 1; i++) {
    DSA.myarray[i].push_back(',');
  }
  return comma;
}

void DynamicStringArray::IncreaseCapacity() {
   const int oldsize = arraysize;
   arraysize += 10;
   std::string* newarray = new std::string[arraysize];
   for (int i = 0; i < oldsize; i++) {
      newarray[i] = myarray[i];
   }
   delete [] myarray;
   myarray = NULL;
   std::swap(myarray, newarray);
}

std::string DynamicStringArray::ToUpper(std::string letter) {
  for (unsigned int i = 0; i < letter.length(); i++) {
    letter.at(i) = toupper(letter.at(i));    
  }
  return letter;
}


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
#ifndef DYNAMIC_STRING_ARRAY_H
#define DYNAMIC_STRING_ARRAY_H
#include <string>
#include <climits>

class DynamicStringArray {
public:
  DynamicStringArray();
  explicit DynamicStringArray(int size = 10);
  ~DynamicStringArray();
  std::string At(int i) const;
  std::string GetFirst();
  std::string GetLast();
  void AddFront(std::string str);
  void AddBack(std::string str);
  void DeleteFront();
  void DeleteBack();
  unsigned GetSize() const;
  unsigned GetCapacity() const;
  bool Empty() const;
  void Clear();
  void Sort();
  std::string ToString(); 
  friend std::ostream& operator<<(std::ostream& comma, const DynamicStringArray& DSA);
private:
  std::string * myarray;
  int arraysize;
  int currentsize;
  void IncreaseCapacity(); 
  std::string ToUpper(std::string letter);
};

#endif /* DYNAMIC_STRING_ARRAY_H */ 
The error is because you don't have a main function.
OK, I did the test and...the code failed. His test codes are hard for me to understand, so it's difficult to see where I went wrong. In order, the cpp file, the header, the test code, and the compiler.

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
#include "dynamic_string_array.h"
#include <iostream>
#include <cmath>
#include <string>
#include <cctype>
#include <sstream>
using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::stringstream;

DynamicStringArray::DynamicStringArray() {
}

DynamicStringArray::DynamicStringArray(int size) : arraysize(size), currentsize(0) {
  myarray = new std::string[arraysize];
}

DynamicStringArray::~DynamicStringArray() {
  delete [] myarray;
  currentsize = 0;
}

std::string DynamicStringArray::At(int i) const {
  if(i > arraysize) {
    throw "Invalid Location";
  }
  return myarray[i];
}

std::string DynamicStringArray::GetFirst() {
  if(currentsize == 0) {
    throw "Array Empty";
  }
  return myarray[0];
}

std::string DynamicStringArray::GetLast() {
  int i = currentsize;
  if(currentsize == 0) {
    throw "Array Empty";
  }
  return myarray[i];
}

void DynamicStringArray::AddFront(std::string str) {
  if(currentsize == arraysize) {
    IncreaseCapacity();
  }
  for (int i = currentsize; i > 0; i--) {
    myarray[i] = myarray[i - 1];
  }
  myarray[0] = str;
  currentsize++;
}
 
void DynamicStringArray::AddBack(std::string str) {
  int i = currentsize;
  if(currentsize == arraysize) {
    IncreaseCapacity();
  }
  myarray[i + 1] = str;
  currentsize++;
}

void DynamicStringArray::DeleteFront() {
  if(currentsize == 0) {
    throw "Array Empty";
  }
  for (int i = 0; i < currentsize; i++) {
    myarray[i] = myarray[i + 1];
  }
  currentsize--;
}

void DynamicStringArray::DeleteBack() {
  int i = currentsize;
  if(currentsize == 0) {
    throw "Array Empty";
  }
  myarray[i] = "";
  currentsize--;
}

unsigned DynamicStringArray::GetSize() const {
  unsigned int size = currentsize;
  return size;
}

unsigned DynamicStringArray::GetCapacity() const {
  unsigned int size = arraysize;
  return size;
}

bool DynamicStringArray::Empty() const {
  bool empty;
  if(currentsize == 0) {
    empty = true;
  } else {
    empty = false;
  }
  return empty;
}

void DynamicStringArray::Clear() {
  delete [] myarray;
  currentsize = 0;
}
 
void DynamicStringArray::Sort() {
  int i;
  int j;
  for (i = 0; i <= (currentsize - 1); i++) {
    j = i;
    while ((j > 0) && (myarray[j] < myarray[j - 1])) {
      std::swap(myarray[j], myarray[j - 1]);
      j = j - 1;
    }
  }
}

std::string DynamicStringArray::ToString() {
  std::stringstream ss;
  ss << *this;
  return ss.str();
}

std::ostream& operator<<(std::ostream& comma, const DynamicStringArray& DSA) {
  for (int i = 0; i < DSA.currentsize - 1; i++) {
    DSA.myarray[i].push_back(',');
  }
  return comma;
}

void DynamicStringArray::IncreaseCapacity() {
   const int oldsize = arraysize;
   arraysize += 10;
   std::string* newarray = new std::string[arraysize];
   for (int i = 0; i < oldsize; i++) {
      newarray[i] = myarray[i];
   }
   delete [] myarray;
   myarray = NULL;
   std::swap(myarray, newarray);
}

std::string DynamicStringArray::ToUpper(std::string letter) {
  for (unsigned int i = 0; i < letter.length(); i++) {
    letter.at(i) = toupper(letter.at(i));    
  }
  return letter;
}

int main() {
}


Header:

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
#ifndef DYNAMIC_STRING_ARRAY_H
#define DYNAMIC_STRING_ARRAY_H
#include <string>
#include <climits>

class DynamicStringArray {
public:
  DynamicStringArray();
  explicit DynamicStringArray(int size = 10);
  ~DynamicStringArray();
  std::string At(int i) const;
  std::string GetFirst();
  std::string GetLast();
  void AddFront(std::string str);
  void AddBack(std::string str);
  void DeleteFront();
  void DeleteBack();
  unsigned GetSize() const;
  unsigned GetCapacity() const;
  bool Empty() const;
  void Clear();
  void Sort();
  std::string ToString();
  friend std::ostream& operator<<(std::ostream& comma, const DynamicStringArray& DSA);
private:
  std::string * myarray;
  int arraysize;
  int currentsize;
  void IncreaseCapacity();
  std::string ToUpper(std::string letter);
};

#endif /* DYNAMIC_STRING_ARRAY_H */ 


Test:

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
/*
 *
 *
 *
 *
 */

#include <iostream>
#include <sstream>
#include <streambuf>
#include "dynamic_string_array.h"
using std::cout;
using std::endl;
using std::string;

// For testing (DO NOT ALTER)
#include <cctype>
#include <vector>
void Test(bool test, string more_info = "");
void UnitTest();
void OutputFailedTests();
unsigned int ut_passed = 0, ut_failed = 0, ut_total = 0, num_of_tests = 0;
std::vector<int> failed_tests;

// Program Execution Starts Here
int main() {
  // START DEBUGGING CODE

  // END DEBUGINH CODE
  // To test your code (DO NOT ALTER)
  UnitTest();
  // This ends program execution
  return 0;
}

// For testing (DO NOT ALTER)
void UnitTest() {
  cout << string(40, '-') << endl;
  cout << "UNIT TEST:\n" << string(40, '-') << endl;
  if (num_of_tests != 0)
    cout << "Total Number of Tests: " << num_of_tests << endl;

  // Tests
  cout << "\n*****Constructor*****\n";
  DynamicStringArray list;
  Test(list.GetSize() == 0, "GetSize()");
  Test(list.GetCapacity() == 10, "GetCapacity()");
  Test(list.ToString() == "", "ToString()");
  Test(list.Empty() == true, "Empty()");

  try {
    list.At(0);
  } catch (const string &e) {
    Test(e == "Invalid Location", "At(0) EXCEPTION HANDLING");
  }

  try {
    list.GetFirst();
  } catch (const string &e) {
    Test(e == "Array Empty", "GetFirst() EXCEPTION HANDLING");
  }

  try {
    list.GetLast();
  } catch (const string &e) {
    Test(e == "Array Empty", "GetLast() EXCEPTION HANDLING");
  }

  try {
    list.DeleteFront();
  } catch (const string &e) {
    Test(e == "Array Empty", "DeleteFront() EXCEPTION HANDLING");
  }

  try {
    list.DeleteBack();
  } catch (const string &e) {
    Test(e == "Array Empty", "DeleteBack() EXCEPTION HANDLING");
  }

  cout << "\n*****Member Functions with 1 Item*****\n";
  list.AddFront(new string("Hello"));
  Test(list.GetSize() == 1, "AddFront(\"Hello\") && GetSize()");
  Test(list.GetCapacity() == 10, "GetCapacity()");
  Test(list.ToString() == "Hello", "ToString()");
  Test(list.Empty() == false, "Empty()");
  try {
    list.At(1);
  } catch (const string &e) {
    Test(e == "Invalid Location", "At(1) EXCEPTION HANDLING");
  }
  Test(*list.At(0) == "Hello", "At(0)");
  Test(*list.GetFirst() == "Hello", "GetFirst()");
  Test(*list.GetLast() == "Hello", "GetLast()");
  cout << "Testing Overloaded <<:\n" << list << endl;

  cout << "\n*****Changing \"Hello\" to \"Goodbye\"*****\n";
  *list.At(0) = "Goodbye";
  Test(list.GetSize() == 1, "GetSize()");
  Test(list.GetCapacity() == 10, "GetCapacity()");
  Test(list.ToString() == "Goodbye", "ToString()");
  Test(*list.At(0) == "Goodbye", "At(0)");
  Test(*list.GetFirst() == "Goodbye", "GetFirst()");
  Test(*list.GetLast() == "Goodbye", "GetLast()");
  cout << "Testing Overloaded <<:\n" << list << endl;

  cout << "\n*****Testing Deletion*****\n";
  list.DeleteFront();
  Test(list.GetSize() == 0, "DeleteFront() && GetSize()");
  list.AddFront(new string("Hello"));
  list.DeleteBack();
  Test(list.GetSize() == 0, "AddFront(), DeleteBack() && GetSize()");

  cout << "\n*****Member Functions with 2 Items*****\n";
  list.AddFront(new string("Goodbye"));
  list.AddFront(new string("Hello"));
  Test(list.GetSize() == 2,
       "AddFront(\"Goodbye\"), AddFront(\"Hello\"), && GetSize()");
  Test(list.GetCapacity() == 10, "GetCapacity()");
  Test(list.ToString() == "Hello, Goodbye", "ToString()");
  Test(list.Empty() == false, "Empty()");
  Test(*list.At(1) == "Goodbye", "At(0)");
  Test(*list.GetFirst() == "Hello", "GetFirst()");
  Test(*list.GetLast() == "Goodbye", "GetLast()");
  cout << "Testing Overloaded <<:\n" << list << endl;

  cout << "\n*****Testing Deletion*****\n";
  list.DeleteBack();
  Test(list.GetSize() == 1, "DeleteBack() && GetSize()");
  Test(list.ToString() == "Hello", "ToString()");
  list.DeleteFront();
  Test(list.GetSize() == 0, "DeleteFront() && GetSize()");
  Test(list.ToString() == "", "ToString()");

  cout << "\n*****Member Functions with 10 Items*****\n";
  stringstream ss;
  for (int i = 0; i < 10; i++) {
    if (i % 2 == 0) {
      ss << "StRiNg #" << i + 1;
      list.AddFront(new string(ss.str()));
    } else {
      ss << "sTrInG #" << i + 1;
      list.AddBack(new string(ss.str()));
    }
    ss.str("");
  }
  Test(list.GetSize() == 10, "Alternating AddFront && AddBack(), && GetSize()");
  Test(list.GetCapacity() == 10, "GetCapacity()");
  Test(list.ToString() == "StRiNg #9, StRiNg #7, StRiNg #5, StRiNg #3, StRiNg #"
      "1, sTrInG #2, sTrInG #4, sTrInG #6, sTrInG #8, sTrIn"
      "G #10",
       "ToString()");
  Test(list.Empty() == false, "Empty()");
  Test(*list.At(3) == "StRiNg #3", "At(3)");
  Test(*list.At(6) == "sTrInG #4", "At(6)");
  try {
    list.At(10);
  } catch (const string &e) {
    Test(e == "Invalid Location", "At(10) EXCEPTION HANDLING");
  }
  Test(*list.GetFirst() == "StRiNg #9", "GetFirst()");
  Test(*list.GetLast() == "sTrInG #10", "GetLast()");
  cout << "Testing Overloaded <<:\n" << list << endl;

  list.Sort();
  Test(list.ToString() == "StRiNg #1, sTrInG #10, sTrInG #2, StRiNg #3, sTrInG "
      "#4, StRiNg #5, sTrInG #6, StRiNg #7, sTrInG #8, StRi"
      "Ng #9",
       "Sort() && ToString()");
  cout << "Testing Overloaded <<:\n" << list << endl;

  cout << "\n*****Testing Deletion*****\n";
  for (unsigned int i = 0; i < 5; i++) {
    list.DeleteBack();
    list.DeleteFront();
  }

  Test(list.GetSize() == 0, "DeleteBack() / DeleteFront() x 10 && GetSize()");
  Test(list.ToString() == "", "ToString()");

  try {
    list.At(0);
  } catch (const string &e) {
    Test(e == "Invalid Location", "At(0) EXCEPTION HANDLING");
  }

  try {
    list.GetFirst();
  } catch (const string &e) {
    Test(e == "Array Empty", "GetFirst() EXCEPTION HANDLING");
  }

  try {
    list.GetLast();
  } catch (const string &e) {
    Test(e == "Array Empty", "GetLast() EXCEPTION HANDLING");
  }

  try {
    list.DeleteFront();
  } catch (const string &e) {
    Test(e == "Array Empty", "DeleteFront() EXCEPTION HANDLING");
  }

  try {
    list.DeleteBack();
  } catch (const string &e) {
    Test(e == "Array Empty", "DeleteBack() EXCEPTION HANDLING");
  }

  cout << "\n*****Member Functions with 31 Items*****\n";

  for (int i = 0; i < 31; i++) {
    if (i % 2 == 0) {
      ss << "StRiNg #" << i + 1;
      list.AddFront(new string(ss.str()));
    } else {
      ss << "sTrInG #" << i + 1;
      list.AddBack(new string(ss.str()));
    }
    ss.str("");
  }
  Test(list.GetSize() == 31, "Alternating AddFront && AddBack(), && GetSize()");
  Test(list.GetCapacity() == 40, "GetCapacity()");
  Test(
      list.ToString()
          == "StRiNg #31, StRiNg #29, StRiNg #27, StRiNg #25, StRiNg #23, StRiN"
              "g #21, StRiNg #19, StRiNg #17, StRiNg #15, StRiNg #13, StRiNg #1"
              "1, StRiNg #9, StRiNg #7, StRiNg #5, StRiNg #3, StRiNg #1, sTrInG"
              " #2, sTrInG #4, sTrInG #6, sTrInG #8, sTrInG #10, sTrInG #12, sT"
              "rInG #14, sTrInG #16, sTrInG #18, sTrInG #20, sTrInG #22, sTrInG"
              " #24, sTrInG #26, sTrInG #28, sTrInG #30",
      "ToString()");
  Test(list.Empty() == false, "Empty()");
  Test(*list.At(3) == "StRiNg #25", "At(3)");
  Test(*list.At(29) == "sTrInG #28", "At(29)");
  try {
    list.At(31);
  } catch (const string &e) {
    Test(e == "Invalid Location", "At(31) EXCEPTION HANDLING");
  }
  Test(*list.GetFirst() == "StRiNg #31", "GetFirst()");
  Test(*list.GetLast() == "sTrInG #30", "GetLast()");
  cout << "Testing Overloaded <<:\n" << list << endl;
Pages: 12