1: // Filename: STRMISC.CPP 2: // Purpose: To show some miscellaneous string operations. 3: // Updated: 11-MAR-2000 19:20:05 to add the "find", "insert", 4: // and "replace" operations. 7: #include <iostream> 8: #include <string> 9: #include <cstring> 10: #include <cstdlib> 11: using namespace std; 13: #include "pause.h" 16: int main() 17: { 18: cout << "\nThis program illustrates a number of " 19: << "additional functions for working with \n" 20: << "C-strings, as well as a number of " 21: << "additional operations available in the \n" 22: << "C++ string class interface. Study " 23: << "the source code while running the program. \n" 24: << "Some of the comments also suggest " 25: << "modifications that you should make, and \n" 26: << "then try the program again. \n\n"; 27: Pause(0); 31: // First some additional functions for working with C-strings: 33: // ***************************************************************** 34: // There are two functions from stdlib.h that are very helpful when 35: // you want to convert a string which "looks like" a number to an 36: // actual number. Here they are: 37: // atoi(s) returns the integer form of the string s. 38: // atof(s) returns the floating point (double) form of the string s. 39: char c_s1[] = "37"; 40: char c_s2[] = "5.1"; 41: // cout << c_s1 * c_s2 << endl; 42: // The above line would (of course) cause a syntax error (try it!), 43: // but the following line works fine: 44: cout << atoi(c_s1) * atof(c_s2) << endl << endl; 45: Pause(0); 48: // ***************************************************************** 49: // Now some additional properties of C++ string objects and some 50: // additional operations in the C++ string class interface: 51: string cpp_s, cpp_s1, cpp_s2; 54: // ***************************************************************** 55: // Often we have to be careful to distinguish between a single 56: // character and a string containing a single character, and in 57: // particular it is worth remembering the following about C++ 58: // strings: 59: cpp_s = 'A'; // This assignment is OK, but neither of the following 60: // initializations in a declaration is OK (try them!): 61: // string s = 'A'; 62: // string s('A'); 63: cout << cpp_s << endl << endl; 64: Pause(0); 67: // ***************************************************************** 68: // Assigning a C-string to a C++ string object is OK, but (as we 69: // know) we cannot assign anything to a C-string variable, including 70: // a C++ string object. 71: char c_s[] = "This is a C-string."; 72: cpp_s = c_s; 73: cout << cpp_s << endl << endl; 74: Pause(0); 77: // ***************************************************************** 78: // There are two ways to access individual characters in a C++ 79: // string, one of them "safer" than the other. We can use square 80: // brackets just as we do for C-strings, as in 81: // s[i] which accesses the character at index "i" in s, 82: // or we can use the "at" operation, as in 83: // s.at(i) which also accesses the character at index "i" in s. 84: // The difference is that there is no out-of-bounds error checking 85: // when using square brackets (to be consistent with the normal use 86: // of square brackets for array component access), but there *is* 87: // out-of-bounds error checking when using "at". 88: cpp_s1 = "man"; 89: cpp_s2 = "man"; 90: cout << cpp_s1 << " " << cpp_s2 << endl; 91: cpp_s1[2] = cpp_s2.at(0) = 't'; 92: cout << cpp_s1 << " " << cpp_s2 << endl; 93: // The following two lines of code "work" because there is no error 94: // checking when brackets are used to access a character location 95: // that does not "belong to " the string. 96: cpp_s1[3] = 'e'; 97: cout << cpp_s1 << endl << endl; 98: // But, the following two lines of code do *not* work because there 99: // *is* error checking when the "at" operation is used. The error 100: // occurs at run-time since that is when the attempted access takes 101: // place. Try running the program with these two lines uncommented. 102: // cpp_s2.at(3) = 'g'; 103: // cout << cpp_s2 << endl; 104: Pause(0); 107: // ***************************************************************** 108: // We can always "extract" the C-string equivalent from a C++ string 109: // object with the c_str() operation as follows: 110: // s.c_str() returns a \0 terminated array of characters containing 111: // the characters in the string s. 112: // Sometimes this is in fact necessary, as for example when we are 113: // passing a string parameter to the open() function of the fstream 114: // class (as you know), or to the system() function from stdlib.h. 115: // Simply displayed on the standard output, however, the two forms 116: // are (of course) indistinguishable: 117: cpp_s = "Hello, world!"; 118: cout << cpp_s << " " << cpp_s.c_str() << endl << endl; 119: Pause(0); 122: // ***************************************************************** 123: // There is a "built-in" swap operation for C++ strings: 124: cpp_s1 = "Hello!"; 125: cpp_s2 = "Good-bye!"; 126: cout << cpp_s1 << " " << cpp_s2 << endl; 127: cpp_s1.swap(cpp_s2); 128: cout << cpp_s1 << " " << cpp_s2 << endl << endl; 129: Pause(0); 132: // ***************************************************************** 133: // There are a number of operations which provide "stats" on various 134: // aspects of a string object: 135: // s.size() returns the number of characters currently in s. 136: // s.length() returns exactly the same thing as s.size(). 137: // s.max_size() returns the largest possible number of characters 138: // that a string object can hold. 139: // s.empty() returns true or false, depending on whether s currently 140: // contains any characters. 141: // And if we'd like to *make* it empty, we can with this operation: 142: // s.clear() 143: cpp_s = "Hello, world!"; 144: cout << cpp_s.size() << " " 145: << cpp_s.length() << " " 146: << cpp_s.max_size() << endl; 147: cout << "Is the string empty? " 148: << (cpp_s.empty() ? "Yes!" : "No!") << endl; 149: //cpp_s.clear(); // Not available in Visual C++ 150: cout << "Is the string empty? " 151: << (cpp_s.empty() ? "Yes!" : "No!") << endl; 152: // The public, static constant "npos" is a member of the string 153: // class and is often the value returned by various operations on 154: // C++ string objects, depending on the outcome of the operation. 155: cout << "Value of \"npos\" is: " << string::npos << endl; 156: cout << "Value of \"npos\" cast to an int value is: " 157: << (int)string::npos << endl << endl; 158: // So note that the value of npos is *not* an int to begin with. 159: // This is a potential problem, and a problem with the Standard. 160: Pause(0); 163: // ***************************************************************** 164: // There is also an "erase" operation that provides a little more 165: // flexibility than the "clear" operation mentioned above: 166: // s.erase() works exactly like s.clear(). 167: // s.erase(i) erases all characters from index "i" onward. 168: // s.erase(i, num) erases "num" characters starting at index "i". 169: cpp_s = "Hello, world!"; 170: cpp_s.erase(5); 171: cout << cpp_s << endl; 172: cpp_s = "Hello, world!"; 173: cpp_s.erase(5, 7); 174: cout << cpp_s << endl << endl; 175: Pause(0); 178: // ***************************************************************** 179: // Another handy operation is that for extracting a substring from 180: // a given string, which looks like this: 181: // s.substr(startIndex, numChars) returns the substring of s 182: // starting at "startIndex" and containing "numChars" characters. 183: cpp_s = "Hello, world!"; 184: cout << cpp_s.substr(7, 5) 185: << cpp_s.substr(5, 2) 186: << cpp_s.substr(0, 5) 187: << cpp_s.substr(12, 1) << endl << endl; 188: Pause(0); 191: // ***************************************************************** 192: // There are some "find" operations that allow us to search through 193: // a string to find one or more characters: 194: // s1.find(s2) 195: // s1.rfind(s2) 196: // s1.find_first_of(s2) 197: // s1.find_last_of(s2) 198: // s1.find_first_not_of(s2) 199: // s1.find_last_not_of(s2) 200: cpp_s = "Now is the time to get serious and get the lead out."; 201: cout << cpp_s.find("the") << endl; 202: cout << cpp_s.rfind("the") << endl; 203: cout << cpp_s.find_first_of("the") << endl; 204: cout << cpp_s.find_last_of("the") << endl; 205: cout << cpp_s.find_first_not_of("Now the out.") << endl; 206: cout << cpp_s.find_last_not_of("Now the out.") << endl << endl; 207: Pause(0); 210: // ***************************************************************** 211: // There are some "insert" operations that allow us to insert one or 212: // more characters into a string: 213: // s1.insert(beforeIndex, s2); 214: // s1.insert(beforeIndex, s2, startIndex, numChars); 215: cpp_s = "Now is to get serious get the lead out."; 216: cpp_s.insert(7, "the time "); 217: cout << cpp_s << endl; 218: cpp_s.insert(31, "oh my, and woe is me", 7, 4); 219: cout << cpp_s << endl << endl; 220: Pause(0); 223: // ***************************************************************** 224: // There are some "replace" operations that allow us to replace one 225: // or more characters in a string: 226: // s1.replace(startIndex, numChars, s2); 227: // s1.replace(startIndex, numChars1, s2, startIndex2, numChars2); 228: cpp_s = "Now is the time to get serious and get the lead out."; 229: cpp_s.replace(7, 3, "that"); 230: cout << cpp_s << endl; 231: cpp_s.replace(24, 7, "smartypants" , 0, 5); 232: cout << cpp_s << endl << endl; 233: Pause(0); 235: return 0; 236: }