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