Выбрать главу

  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, char objects) and will not replace quoted char arrays or string objects. Since a string behaves 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 string member functions.

Concatenation using nonmember overloaded operators

One of the most delightful discoveries awaiting a C programmer learning about C++ string handling 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 <string>

#include <cassert>

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 string data. On the right side of the statement, you can use almost any type that evaluates to a group of one or more characters.

Searching in strings

The find family of string member functions allows you to locate a character or group of characters within a given string. Here are the members of the find family 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. (npos is a const of –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 find inside 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 sieveChars using 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 <cmath>

#include <cstddef>

#include <string>

#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;

    int root = int(sqrt(double(p)));

    for (int i = 2; i <= root; ++i)

      if (p % i == 0) return false;

    return true;

  }

  void findPrimes() {

    // By definition neither 0 nor 1 is prime.

    // Change these elements to "N" for Not Prime

    sieveChars.replace(0, 2, "NN");

    // Walk through the array:

    size_t sieveSize = sieveChars.size();

    int root = int(sqrt(double(sieveSize)));

    for (int i = 2; i <= root; ++i)

      // Find all the multiples:

      for (size_t factor = 2; factor * i < sieveSize;

           ++factor)

        sieveChars[factor * i] = 'N';

  }

  void testPrimes() {

    size_t i = sieveChars.find('P');

    while (i != string::npos) {