string成员函数中的find族是用来在给定字符串中定位某个或某组
字符的。
find()最简单应用就是在string对象中查找一个或多个字符
用Erotosthenes筛选法查找小于50的素数
从2开始,标记所有2 3,5... 倍数为非素数,对其他后选素数重复该
过程
SieveTest的构造函数对sieveChars进行初始化,设置其字符序列
array 的初始大小,并且用‘P’来填充每个成员
//: C03:Sieve.h
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
#ifndef SIEVE_H
#define SIEVE_H
#include <cmath>
#include <cstddef>
#include <string>
#include "../TestSuite/Test.h"
using std::size_t;
using std::sqrt;
using std::string;
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) {
test_(isPrime(i++));
i = sieveChars.find('P', i);
}
i = sieveChars.find_first_not_of('P');
while(i != string::npos) {
test_(!isPrime(i++));
i = sieveChars.find_first_not_of('P', i);
}
}
};
#endif // SIEVE_H ///:~
//: C03:Sieve.cpp
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
//{L} ../TestSuite/Test
#include "Sieve.h"
int main() {
SieveTest t;
t.run();
return t.report();
getchar();
} ///:~
find()函数在string内部进行搜索,检测多次出现的一个字符或
字符组,find_first_not_of()查找其他的字符或子串
命令行输出
Test "class SieveTest":
Passed: 50 Failed: 0
用vs窗口出现一下就关闭
补充剩下的 Test.cpp Test.h
//: TestSuite:Test.h
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
#ifndef TEST_H
#define TEST_H
#include <string>
#include <iostream>
#include <cassert>
using std::string;
using std::ostream;
using std::cout;
// fail_() has an underscore to prevent collision with
// ios::fail(). For consistency, test_() and succeed_()
// also have underscores.
#define test_(cond) \
do_test(cond, #cond, __FILE__, __LINE__)
#define fail_(str) \
do_fail(str, __FILE__, __LINE__)
namespace TestSuite {
class Test {
ostream* osptr;
long nPass;
long nFail;
// Disallowed:
Test(const Test&);
Test& operator=(const Test&);
protected:
void do_test(bool cond, const string& lbl,
const char* fname, long lineno);
void do_fail(const string& lbl,
const char* fname, long lineno);
public:
Test(ostream* osptr = &cout) {
this->osptr = osptr;
nPass = nFail = 0;
}
virtual ~Test() {}
virtual void run() = 0;
long getNumPassed() const { return nPass; }
long getNumFailed() const { return nFail; }
const ostream* getStream() const { return osptr; }
void setStream(ostream* osptr) { this->osptr = osptr; }
void succeed_() { ++nPass; }
long report() const;
virtual void reset() { nPass = nFail = 0; }
};
} // namespace TestSuite
#endif // TEST_H ///:~
//: TestSuite:Test.cpp {O}
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
#include "Test.h"
#include <iostream>
#include <typeinfo>
using namespace std;
using namespace TestSuite;
void Test::do_test(bool cond, const std::string& lbl,
const char* fname, long lineno) {
if(!cond)
do_fail(lbl, fname, lineno);
else
succeed_();
}
void Test::do_fail(const std::string& lbl,
const char* fname, long lineno) {
++nFail;
if(osptr) {
*osptr << typeid(*this).name()
<< "failure: (" << lbl << ") , " << fname
<< " (line " << lineno << ")" << endl;
}
}
long Test::report() const {
if(osptr) {
*osptr << "Test \"" << typeid(*this).name()
<< "\":\n\tPassed: " << nPass
<< "\tFailed: " << nFail
<< endl;
}
return nFail;
} ///:~
string类中没有改变字符串大小写的函数,但借助于标准C语言的库
函数toupper()和tolower(),可很容易地创建这类函数
//: C03:Find.h
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
#ifndef FIND_H
#define FIND_H
#include <cctype>
#include <cstddef>
#include <string>
#include "../TestSuite/Test.h"
using std::size_t;
using std::string;
using std::tolower;
using std::toupper;
// Make an uppercase copy of s
inline string upperCase(const string& s) {
string upper(s);
for(size_t i = 0; i < s.length(); ++i)
upper[i] = toupper(upper[i]);
return upper;
}
// Make a lowercase copy of s
inline string lowerCase(const string& s) {
string lower(s);
for(size_t i = 0; i < s.length(); ++i)
lower[i] = tolower(lower[i]);
return lower;
}
class FindTest : public TestSuite::Test {
string chooseOne;
public:
FindTest() : chooseOne("Eenie, Meenie, Miney, Mo") {}
void testUpper() {
string upper = upperCase(chooseOne);
const string LOWER = "abcdefghijklmnopqrstuvwxyz";
test_(upper.find_first_of(LOWER) == string::npos);
}
void testLower() {
string lower = lowerCase(chooseOne);
const string UPPER = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
test_(lower.find_first_of(UPPER) == string::npos);
}
void testSearch() {
// Case sensitive search
size_t i = chooseOne.find("een");
test_(i == 8);
// Search lowercase:
string test = lowerCase(chooseOne);
i = test.find("een");
test_(i == 0);
i = test.find("een", ++i);
test_(i == 8);
i = test.find("een", ++i);
test_(i == string::npos);
// Search uppercase:
test = upperCase(chooseOne);
i = test.find("EEN");
test_(i == 0);
i = test.find("EEN", ++i);
test_(i == 8);
i = test.find("EEN", ++i);
test_(i == string::npos);
}
void run() {
testUpper();
testLower();
testSearch();
}
};
#endif // FIND_H ///:~
//: C03:Find.cpp
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
//{L} ../TestSuite/Test
#include "Find.h"
#include "../TestSuite/Test.h"
int main() {
FindTest t;
t.run();
return t.report();
} ///:~
upperCase()和lowerCase()两个函数的流程形式相同:它们先复制
参数string对象,接着改变其大小写
输出
Test "class FindTest":
Passed: 9 Failed: 0