⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chap04.htm

📁 C++编程思想第二版第二卷
💻 HTM
📖 第 1 页 / 共 5 页
字号:
</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(&#160;)
</B>searches for one or more characters in a <B>string</B>. This overloaded
version of <B>find(&#160;) </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 &#8216;P&#8217; 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 &lt;string&gt;
#include &lt;iostream&gt;
<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 &lt;= (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 &lt; sieveChars.size();factor++)
      sieveChars[factor * i] = 'N';
     
  cout &lt;&lt; <font color=#004488>"Prime:"</font> &lt;&lt; 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 &lt;&lt; j &lt;&lt; <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 &lt;&lt; <font color=#004488>"\n Not prime:"</font> &lt;&lt; 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 &lt;&lt; j &lt;&lt; <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(&#160;)</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(&#160;)</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 &lt;string&gt;
#include &lt;iostream&gt;
<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 &lt;&lt; i &lt;&lt; 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
&#8216;e&#8217; of the search group &#8220;een&#8221; was found in the word
&#8220;meenie,&#8221; and is the eighth element in the string. Notice that
<B>find</B> passed over the &#8220;Een&#8221; group of characters in the word
&#8220;Eenie&#8221;. 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(&#160;)</B> and
<B>tolower(&#160;)</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 &lt;string&gt;
#include &lt;iostream&gt;
<font color=#0000ff>using</font> <font color=#0000ff>namespace</font> std;

<font color=#009900>// Make an uppercase copy of s:</font>
string upperCase(string&amp; 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 &lt; 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&amp; 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 &lt; 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 &lt;&lt; chooseOne &lt;&lt; endl;
  cout &lt;&lt; upperCase(chooseOne) &lt;&lt; endl;
  cout &lt;&lt; lowerCase(chooseOne) &lt;&lt; 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 &lt;&lt; i &lt;&lt; endl;
    i++;
    i = chooseOne.find(<font color=#004488>"een"</font>, i);
  }
  <font color=#009900>// Search lowercase:</font>
  string lcase = lowerCase(chooseOne);
  cout &lt;&lt; lcase &lt;&lt; endl;
  i = lcase.find(<font color=#004488>"een"</font>);
  <font color=#0000ff>while</font>(i != lcase.npos) {
    cout &lt;&lt; i &lt;&lt; endl;
    i++;
    i = lcase.find(<font color=#004488>"een"</font>, i);
  }
  <font color=#009900>// Search uppercase:</font>
  string ucase = upperCase(chooseOne);
  cout &lt;&lt; ucase &lt;&lt; endl;
  i = ucase.find(<font color=#004488>"EEN"</font>);
  <font color=#0000ff>while</font>(i != ucase.npos) {
    cout &lt;&lt; i &lt;&lt; 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(&#160;)</B> and
<B>lowerCase(&#160;)</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(&#160;)</B> function cannot be
used to produce a pointer to directly manipulate the data in the <B>string</B>
because <B>c_str(&#160;)</B> returns a pointer to <B>const</B>. That is,
you&#8217;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 &#8220;een&#8221; group. </FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia"><B>NewFind.cpp</B> isn&#8217;t the best
solution to the case sensitivity problem, so we&#8217;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&#8217;s necessary to search
through a <B>string</B> from end to beginning, if you need to find the data in
&#8220;last in / first out &#8220; order. The string member function
<B>rfind(&#160;)</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 &lt;string&gt;
#include &lt;iostream&gt;
#include &lt;vector&gt;
<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 &lt;&lt; s &lt;&lt; endl;
  <font color=#009900>// To store the words:</font>
  vector&lt;string&gt; 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 + -