//: C03:ReplaceAll.cpp {O}
#include
#include
using namespace std;
string& replaceAll(string& context, const string& from,
const string& to) {
size_t lookHere = 0;
size_t foundHere;
while ((foundHere = context.find(from, lookHere))
!= string::npos) {
context.replace(foundHere, from.size(), to);
lookHere = foundHere + to.size();
}
return context;
} ///:~
The version of find( )used here takes as a second argument the position to start looking in and returns string::nposif it doesn’t find it. It is important to advance the position held in the variable lookHerepast the replacement string, of course, in case fromis a substring of to. The following program tests the replaceAllfunction: .
//: C03:ReplaceAllTest.cpp
//{-msc}
//{L} ReplaceAll
#include
#include
using namespace std;
string& replaceAll(string& context, const string& from,
const string& to);
int main() {
string text = "a man, a plan, a canal, panama";
replaceAll(text, "an", "XXX");
assert(text == "a mXXX, a plXXX, a cXXXal, pXXXama");
} ///:~
As you can see, the stringclass by itself doesn’t solve all possible problems. Many solutions have been left to the algorithms in the Standard library, [31] Discussed in depth in Chapter 6.
because the stringclass can look just like an STL sequence (by virtue of the iterators discussed earlier). All the generic algorithms work on a "range" of elements within a container. Usually that range is just "from the beginning of the container to the end." A stringobject looks like a container of characters: to get the beginning of the range you use string::begin( ),and to get the end of the range you use string::end( ). The following example shows the use of the replace( )algorithm to replace all the instances of the single character ‘X’ with ‘Y’: .
//: C03:StringCharReplace.cpp
#include
#include
#include
using namespace std;
int main() {
string s("aaaXaaaXXaaXXXaXXXXaaa");
replace(s.begin(), s.end(), 'X', 'Y');
assert(s == "aaaYaaaYYaaYYYaYYYYaaa");
} ///:~
Notice that this replace( )is not called as a member function of string. Also, unlike the string::replace( )functions that only perform one replacement, the replace( )algorithm replaces all instances of one character with another .
The replace( )algorithm only works with single objects (in this case, charobjects) and will not replace quoted chararrays or stringobjects. Since a stringbehaves like an STL sequence, a number of other algorithms can be applied to it, which might solve other problems that are not directly addressed by the stringmember functions .
Concatenation using nonmember overloaded operators
One of the most delightful discoveries awaiting a C programmer learning about C++ stringhandling is how simply strings can be combined and appended using operator+and operator+=. These operators make combining strings syntactically similar to adding numeric data .
//: C03:AddStrings.cpp
#include
#include
using namespace std;
int main() {
string s1("This ");
string s2("That ");
string s3("The other ");
// operator+ concatenates strings
s1 = s1 + s2;
assert(s1 == "This That ");
// Another way to concatenates strings
s1 += s3;
assert(s1 == "This That The other ");
// You can index the string on the right
s1 += s3 + s3[4] + "ooh lala";
assert(s1 == "This That The other The other "
"oooh lala");
} ///:~
Using the operator+and operator+=operators is a flexible and convenient way to combine stringdata. On the right side of the statement, you can use almost any type that evaluates to a group of one or more characters .
The findfamily of stringmember functions allows you to locate a character or group of characters within a given string. Here are the members of the findfamily and their general usage :
string find member function |
What/how it finds |
find( ) |
Searches a string for a specified character or group of characters and returns the starting position of the first occurrence found or npos if no match is found. ( nposis a constof –1 [cast as a std::size_t] and indicates that a search failed.) |
find_first_of( ) |
Searches a target string and returns the position of the first match of any character in a specified group. If no match is found, it returns npos. |
find_last_of( ) |
Searches a target string and returns the position of the last match of any character in a specified group. If no match is found, it returns npos. |
find_first_not_of( ) |
Searches a target string and returns the position of the first element that doesn’t match any character in a specified group. If no such element is found, it returns npos. |
find_last_not_of( ) |
Searches a target string and returns the position of the element with the largest subscript that doesn’t match any character in a specified group. If no such element is found, it returns npos. |
rfind( ) |
Searches a string from end to beginning for a specified character or group of characters and returns the starting position of the match if one is found. If no match is found, it returns npos. |
The simplest use of find( )searches for one or more characters in a string. This overloaded version of find( )takes a parameter that specifies the character(s) for which to search and optionally a parameter that tells it where in the string to begin searching for the occurrence of a substring. (The default position at which to begin searching is 0.) By setting the call to findinside a loop, you can easily move through a string, repeating a search to find all the occurrences of a given character or group of characters within the string .
The following program uses the method of The Sieve of Eratosthenes to find prime numbers less than 50. This method starts with the number 2, marks all subsequent multiples of 2 as not prime, and repeats the process for the next prime candidate. Notice that we define the string object sieveCharsusing a constructor idiom that sets the initial size of the character array and writes the value ‘P’ to each of its member .
//: C03:Sieve.cpp
//{L} ../TestSuite/Test
#include
#include
#include
#include "../TestSuite/Test.h"
using namespace std;
class SieveTest : public TestSuite::Test {
string sieveChars;
public:
// Create a 50 char string and set each
// element to 'P' for Prime
SieveTest() : sieveChars(50, 'P') {}
void run() {
findPrimes();
testPrimes();
}
bool isPrime(int p) {
if (p == 0 || p == 1) return false;
Читать дальше