// stringmain.cpp - tests/demonstrates Nagler text's class String // (from Learning C++: A Hands on Approach, by Eric Nagler) // entered/tested by cmc, 8/12/03 - reorganized 10/30/13 #include "string.h" #include using namespace std; // declare test functions that are implemented below main void convertAndSearchTest(), copyTest(), refreshTest(), countTest(), joinTest(), binaryPlusTest(), assignmentTest(), funcCallOpTest(), subscriptTest(), plusEqualsTest(), incrementTest(); int main() { struct { // encapsulated test name and related function pointer String name; void (*func)(); } tests[] = { // stored in an array for convenient access { "converting ctor and search test", &convertAndSearchTest }, { "copy test", ©Test }, { "refresh and toUpper test", &refreshTest }, { "instance count test", &countTest }, { "join test", &joinTest }, { "binary operator+ test", &binaryPlusTest }, { "operator= test", &assignmentTest }, { "operator() test", &funcCallOpTest }, { "operator[] test", &subscriptTest }, { "operator+= test", &plusEqualsTest }, { "operator++ test", &incrementTest } }; int size = sizeof tests / sizeof tests[0]; cout << "\nChoices:\n"; for (int i = 0; i < size; i++) cout << " " << i + 1 << ". " << tests[i].name << '\n'; cout << " " << size+1 << ". All tests\n"; int choice; cout << "Enter choice --> "; cin >> choice; cout << '\n'; if (choice > 0 && choice <= size) tests[choice-1].func(); else if (choice == size+1) for (int i = 0; i < size; i++) { tests[i].func(); cout << "********************\n"; } else cerr << "bad choice\n"; } // Note: everything below this comment is from chapters 7-8 void convertAndSearchTest() { // Nagler p. 130 cout << "Converting constructors and search tests:\n"; String const masterString("C++"); if (masterString.search("+")) // converts from char const * cout << "found \"+\" in C++\n"; if (masterString.search('C')) // converts from char cout << "found \'C\' in C++\n"; if (masterString.search('D')) // extra test of search cerr << "found D in C++ - search not working\n"; } void copyTest() { // p. 138 cout << "Copy constructor tests:\n"; String s("C++"); String copy1(s); // C++ style initialization of copy String copy2 = copy1; // C style initialization of copy if (s.search(copy2) && copy2.search(s) && (&s != ©1) && (©1 != ©2) ) cout << "made 2 good copies\n"; else cerr << "copy constructor not working\n"; } void refreshTest() { // p. 169 String str("C"); cout << "Refresh and toUpper tests:\n"; cout << " str before refresh: "; display(str); cout << endl; String language(str.refresh("c++").toUpper()); cout << " str after refresh: "; display(str); cout << endl; cout << " language after chaining: "; display(language); cout << endl; } void countTest() { // p. 175+ cout << "Instance counter tests:\n"; cout << "(Note: initial count now corresponds to number of choices,\n" << " because main created an array of Strings for test names.)\n"; cout << " initial count: " << String::getCount() << endl; String a; String b = a; cout << " count after a, b: " << a.getCount() << endl; String *c = new String; cout << " count after new c: " << a.getCount() << endl; delete c; cout << " count after delete c: " << a.getCount() << endl; } void joinTest() { // p. 186 char const *pLeft = "This is a test"; char const *pRight = " of concatenation"; String str1(pLeft); String str2(pRight); String str3(join(str1, str2)); // rest of joins show use of implicit conversion String str4(join(pLeft, str2)); String str5(join(str1, pRight)); //does not work at CSIL: String str6(join(pLeft, pRight)); cout << "3 string objects after joining them:\n"; display(str3); cout << endl; display(str4); cout << endl; display(str5); cout << endl; //display(str6); cout << endl; } void binaryPlusTest() { // Nagler p. 262 char const *pLeft = "This is a test"; char const *pRight = " of concatenation (using the + operator)"; String str1(pLeft); String str2(pRight); String str3(str1 + str2); String str4(pLeft + str2); String str5(str1 + pRight); // note: (pLeft + pRight) does not work - is pointer arithmetic cout << "3 string objects after + operations:\n"; cout << str3 << endl; cout << str4 << endl; cout << str5 << endl; // note: using operator<< now instead of display() } void assignmentTest() { // p. 268 String str1, str2("C++"); str1 = str2; cout << "Assignment test:\n" << " str1: " << str1 << endl; } void funcCallOpTest() { // p. 271 cout << "Function call operator test (answers should be 2, 1, 2, 1, 0):\n"; String const str("C++"); int answers[] = { str(), str("C+"), str("+"), str("++"), str("D") }; int n = sizeof answers / sizeof(int); for (int i = 0; i < n; i++) cout << " answer " << i + 1 << ": " << answers[i] << endl; } void subscriptTest() { // p. 273 cout << "Subscript tests:\n"; String str1("Mutable string"); String const str2("Constant string"); str1[0] = 'A'; cout << "\"Mutable string\" changed to: \"" << str1 << "\"\n"; str1[0] = str2[0]; // note: uses mutable and constant operator[] cout << "\"Mutable string\" changed to: \"" << str1 << "\"\n"; // str2[0] = 'A'; // would be compiler error like "non lvalue in assignment" } void plusEqualsTest() { // for compound assignment operator char const *pLeft = "This is a test"; char const *pRight = " of compound assignment (using += operator)"; String str1(pLeft); String str2(pRight); String copy1 = str1; str1 += str2; copy1 += pRight; cout << "2 string objects after += operations:\n"; cout << str1 << endl; cout << copy1 << endl; } void incrementTest() { // p. 281 cout << "Increment tests:\n"; String str1("ABC"); cout << " str1 to start: " << str1 << endl; String str2(++str1); cout << " str1 after pre-increment: " << str1 << endl; cout << " str2: " << str2 << endl; String str3(str1++); cout << " str1 after post-increment: " << str1 << endl; cout << " str3: " << str3 << endl; }