📄 chap04.htm
字号:
</TR>
</TABLE></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Verdana"><B>String searching member functions and
their general uses</B></FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The simplest use of <B>find( )
</B>searches for one or more characters in a <B>string</B>. This overloaded
version of <B>find( ) </B>takes a parameter that specifies the character(s)
for which to search, and optionally one 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 <B>find </B>inside a
loop, you can easily move through a string, repeating a search in order to find
all of the occurrences of a given character or group of characters within the
string. </FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Notice that we define the string object
<B>sieveChars</B> using a constructor idiom which sets the initial size of the
character array and writes the value ‘P’ to each of its
member.</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C04:Sieve.cpp</font>
<font color=#009900>//{L} ../TestSuite/Test</font>
#include <string>
#include <iostream>
<font color=#0000ff>using</font> <font color=#0000ff>namespace</font> std;
<font color=#0000ff>int</font> main() {
<font color=#009900>// Create a 50 char string and set each </font>
<font color=#009900>// element to 'P' for Prime</font>
string sieveChars(50, 'P');
<font color=#009900>// By definition neither 0 nor 1 is prime.</font>
<font color=#009900>// Change these elements to "N" for Not Prime</font>
sieveChars.replace(0, 2, <font color=#004488>"NN"</font>);
<font color=#009900>// Walk through the array:</font>
<font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 2;
i <= (sieveChars.size() / 2) - 1; i++)
<font color=#009900>// Find all the factors:</font>
<font color=#0000ff>for</font>(<font color=#0000ff>int</font> factor = 2;
factor * i < sieveChars.size();factor++)
sieveChars[factor * i] = 'N';
cout << <font color=#004488>"Prime:"</font> << endl;
<font color=#009900>// Return the index of the first 'P' element:</font>
<font color=#0000ff>int</font> j = sieveChars.find('P');
<font color=#009900>// While not at the end of the string:</font>
<font color=#0000ff>while</font>(j != sieveChars.npos) {
<font color=#009900>// If the element is P, the index is a prime</font>
cout << j << <font color=#004488>" "</font>;
<font color=#009900>// Move past the last prime</font>
j++;
<font color=#009900>// Find the next prime</font>
j = sieveChars.find('P', j);
}
cout << <font color=#004488>"\n Not prime:"</font> << endl;
<font color=#009900>// Find the first element value not equal P:</font>
j = sieveChars.find_first_not_of('P');
<font color=#0000ff>while</font>(j != sieveChars.npos) {
cout << j << <font color=#004488>" "</font>;
j++;
j = sieveChars.find_first_not_of('P', j);
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The output from <B>Sieve.cpp</B> looks
like this:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE>Prime:
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47
Not prime:
0 1 4 6 8 9 10 12 14 15 16 18 20 21 22
24 25 26 27 28 30 32 33 34 35 36 38 39
40 42 44 45 46 48 49</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia"><B>find( )</B> allows you to walk
forward through a <B>string</B>, detecting multiple occurrences of a character
or group of characters, while <B>find_first_not_of( )</B> allows you to
test for the absence of a character or group.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The <B>find</B> member is also useful for
detecting the occurrence of a sequence of characters in a
<B>string</B>:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C04:Find.cpp</font>
<font color=#009900>// Find a group of characters in a string</font>
<font color=#009900>//{L} ../TestSuite/Test</font>
#include <string>
#include <iostream>
<font color=#0000ff>using</font> <font color=#0000ff>namespace</font> std;
<font color=#0000ff>int</font> main() {
string chooseOne(<font color=#004488>"Eenie, meenie, miney, mo"</font>);
<font color=#0000ff>int</font> i = chooseOne.find(<font color=#004488>"een"</font>);
<font color=#0000ff>while</font>(i != string::npos) {
cout << i << endl;
i++;
i = chooseOne.find(<font color=#004488>"een"</font>, i);
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia"><B>Find.cpp</B> produces a single line of
output :</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE> 8 </PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">This tells us that the first
‘e’ of the search group “een” was found in the word
“meenie,” and is the eighth element in the string. Notice that
<B>find</B> passed over the “Een” group of characters in the word
“Eenie”. The <B>find</B> member function performs a <I>case
sensitive</I> search. </FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">There are no functions in the <B>string
</B>class to change the case of a string, but these functions can be easily
created using the Standard C library functions <B>toupper( )</B> and
<B>tolower( )</B>, which change the case of one character at a time. A few
small changes will make <B>Find.cpp</B> perform a case insensitive
search:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C04:NewFind.cpp</font>
<font color=#009900>//{L} ../TestSuite/Test</font>
#include <string>
#include <iostream>
<font color=#0000ff>using</font> <font color=#0000ff>namespace</font> std;
<font color=#009900>// Make an uppercase copy of s:</font>
string upperCase(string& s) {
<font color=#0000ff>char</font>* buf = <font color=#0000ff>new</font> <font color=#0000ff>char</font>[s.length()];
s.copy(buf, s.length());
<font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 0; i < s.length(); i++)
buf[i] = toupper(buf[i]);
string r(buf, s.length());
<font color=#0000ff>delete</font> buf;
<font color=#0000ff>return</font> r;
}
<font color=#009900>// Make a lowercase copy of s:</font>
string lowerCase(string& s) {
<font color=#0000ff>char</font>* buf = <font color=#0000ff>new</font> <font color=#0000ff>char</font>[s.length()];
s.copy(buf, s.length());
<font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 0; i < s.length(); i++)
buf[i] = tolower(buf[i]);
string r(buf, s.length());
<font color=#0000ff>delete</font> buf;
<font color=#0000ff>return</font> r;
}
<font color=#0000ff>int</font> main() {
string chooseOne(<font color=#004488>"Eenie, meenie, miney, mo"</font>);
cout << chooseOne << endl;
cout << upperCase(chooseOne) << endl;
cout << lowerCase(chooseOne) << endl;
<font color=#009900>// Case sensitive search</font>
<font color=#0000ff>int</font> i = chooseOne.find(<font color=#004488>"een"</font>);
<font color=#0000ff>while</font>(i != string::npos) {
cout << i << endl;
i++;
i = chooseOne.find(<font color=#004488>"een"</font>, i);
}
<font color=#009900>// Search lowercase:</font>
string lcase = lowerCase(chooseOne);
cout << lcase << endl;
i = lcase.find(<font color=#004488>"een"</font>);
<font color=#0000ff>while</font>(i != lcase.npos) {
cout << i << endl;
i++;
i = lcase.find(<font color=#004488>"een"</font>, i);
}
<font color=#009900>// Search uppercase:</font>
string ucase = upperCase(chooseOne);
cout << ucase << endl;
i = ucase.find(<font color=#004488>"EEN"</font>);
<font color=#0000ff>while</font>(i != ucase.npos) {
cout << i << endl;
i++;
i = ucase.find(<font color=#004488>"EEN"</font>, i);
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Both the <B>upperCase( )</B> and
<B>lowerCase( )</B> functions follow the same form: they allocate storage
to hold the data in the argument <B>string</B>, copy the data and change the
case. Then they create a new <B>string</B> with the new data, release the buffer
and return the result <B>string</B>. The <B>c_str( )</B> function cannot be
used to produce a pointer to directly manipulate the data in the <B>string</B>
because <B>c_str( )</B> returns a pointer to <B>const</B>. That is,
you’re not allowed to manipulate <B>string</B> data with a pointer, only
with member functions. If you need to use the more primitive <B>char</B> array
manipulation, you should use the technique shown above.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The output looks like
this:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE>Eenie, meenie, miney, mo
EENIE, MEENIE, MINEY, MO
eenie, meenie, miney, mo
8
eenie, meenie, miney, mo
0
8
EENIE, MEENIE, MINEY, MO
0
8</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The case insensitive searches found both
occurrences on the “een” group. </FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia"><B>NewFind.cpp</B> isn’t the best
solution to the case sensitivity problem, so we’ll revisit it when we
examine <B>string</B> comparisons.</FONT><A NAME="_Toc519041932"></A><BR></P></DIV>
<A NAME="Heading93"></A><FONT FACE = "Verdana, Tahoma, Arial, Helvetica, Sans"><H3 ALIGN="LEFT">
Finding in reverse</H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Sometimes it’s necessary to search
through a <B>string</B> from end to beginning, if you need to find the data in
“last in / first out “ order. The string member function
<B>rfind( )</B> handles this job. </FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C04:Rparse.cpp</font>
<font color=#009900>// Reverse the order of words in a string</font>
<font color=#009900>//{L} ../TestSuite/Test</font>
#include <string>
#include <iostream>
#include <vector>
<font color=#0000ff>using</font> <font color=#0000ff>namespace</font> std;
<font color=#0000ff>int</font> main() {
<font color=#009900>// The ';' characters will be delimiters</font>
string s(<font color=#004488>"now.;sense;make;to;going;is;This"</font>);
cout << s << endl;
<font color=#009900>// To store the words:</font>
vector<string> strings;
<font color=#009900>// The last element of the string:</font>
<font color=#0000ff>int</font> last = s.size();
<font color=#009900>// The beginning of the current word:</font>
<font color=#0000ff>int</font> current = s.rfind(';');
<font color=#009900>// Walk backward through the string:</font>
<font color=#0000ff>while</font>(current != string::npos){
<font color=#009900>// Push each word into the vector.</font>
<font color=#009900>// Current is incremented before copying to </font>
<font color=#009900>// avoid copying the delimiter:</font>
++current;
strings.push_back(
s.substr(current, last - current));
<font color=#009900>// Back over the delimiter we just found, </font>
<font color=#009900>// and set last to the end of the next word:</font>
current -= 2;
last = current;
<font color=#009900>// Find the next delimiter</font>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -