Source of strmisc.cpp


  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: }