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

📄 chap04.htm

📁 C++编程思想第二版第二卷
💻 HTM
📖 第 1 页 / 共 5 页
字号:
  string s4(s1, 0, 8);
  <font color=#009900>// Copy 6 chars from the middle of the source</font>
  string s5(s2, 15, 6);
  <font color=#009900>// Copy from middle to end</font>
  string s6(s3, 6, 15);
  <font color=#009900>// Copy all sorts of stuff</font>
  string quoteMe = s4 + <font color=#004488>"that"</font> +  
  <font color=#009900>// substr() copies 10 chars at element 20</font>
  s1.substr(20, 10) + s5 +
  <font color=#009900>// substr() copies up to either 100 char</font>
  <font color=#009900>// or eos starting at element 5 </font>
  <font color=#004488>"with"</font> + s3.substr(5, 100) +
  <font color=#009900>// OK to copy a single char this way </font>
  s1.substr(37, 1);
  cout &lt;&lt; quoteMe &lt;&lt; endl;
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The <B>string</B> member function
<B>substr(&#160;)</B> takes a starting position as its first argument and the
number of characters to select as the second argument. Both of these arguments
have default values and if you say <B>substr(&#160;)</B> with an empty argument
list you produce a copy of the entire <B>string</B>, so this is a convenient way
to duplicate a <B>string</B>. </FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Here&#8217;s what the <B>string</B>
<B>quoteMe </B>contains after the initialization shown above :</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#004488>"What is that one clam doing with Elvis in a UFO.?"</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Notice the final line of example above.
C++ allows <B>string</B> initialization techniques to be mixed in a single
statement, a flexible and convenient feature. Also note that the last
initializer copies <I>just one character</I> from the source
<B>string</B>.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Another slightly more subtle
initialization technique involves the use of the <B>string</B> iterators
<B>string.begin(&#160;)</B> and <B>string.end(&#160;).</B> This treats a
<B>string</B> like a <I>container</I> object (which you&#8217;ve seen primarily
in the form of <B>vector</B> so far in this book &#8211; you&#8217;ll see many
more containers soon) which has <I>iterators</I> indicating the start and end of
the &#8220;container.&#8221; This way you can hand a <B>string</B> constructor
two iterators and it will copy from one to the other into the new
<B>string</B>:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C04:StringIterators.cpp</font>
<font color=#009900>//{L} ../TestSuite/Test</font>
<font color=#009900>//{-msc} Execution error</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 source(<font color=#004488>"xxx"</font>);
  string s(source.begin(), source.end());
  cout &lt;&lt; s &lt;&lt; endl;
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The iterators are not restricted to
<B>begin(&#160;)</B> and <B>end(&#160;)</B>, so you can choose a subset of
characters from the source <B>string</B>.</FONT><BR></P></DIV>
<A NAME="Heading86"></A><FONT FACE = "Verdana, Tahoma, Arial, Helvetica, Sans"><H4 ALIGN="LEFT">
Initialization limitations</H4></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">C++ <B>string</B>s may <I>not</I> be
initialized with single characters or with ASCII or other integer values.
</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C04:UhOh.cpp</font>
<font color=#009900>//{L} ../TestSuite/Test</font>
<font color=#009900>//{-msc} Execution error</font>
#include &lt;string&gt;
<font color=#0000ff>using</font> <font color=#0000ff>namespace</font> std;

<font color=#0000ff>int</font> main() {
  <font color=#009900>// Error: no single char inits</font>
  <font color=#009900>//! string nothingDoing1('a');</font>
  <font color=#009900>// Error: no integer inits</font>
  <font color=#009900>//! string nothingDoing2(0x37);</font>
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">This is true both for initialization by
assignment and by copy constructor.</FONT><A NAME="_Toc519041927"></A><BR></P></DIV>
<A NAME="Heading87"></A><FONT FACE = "Verdana, Tahoma, Arial, Helvetica, Sans"><H2 ALIGN="LEFT">
Operating on strings</H2></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">If you&#8217;ve programmed in C, you are
accustomed to the convenience of a large family of functions for writing,
searching, rearranging, and copying <B>char</B> arrays. However, there are two
unfortunate aspects of the Standard C library functions for handling <B>char</B>
arrays. First, there are three loosely organized families of them: the
&#8220;plain&#8221; group, the group that manipulates the characters
<I>without</I> respect to case, and the ones which require you to supply a count
of the number of characters to be considered in the operation at hand. The
roster of function names in the C <B>char</B> array handling library literally
runs to several pages, and though the kind and number of arguments to the
functions are somewhat consistent within each of the three groups, to use them
properly you must be very attentive to details of function naming and parameter
passing.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The second inherent trap of the standard
C <B>char</B> array tools is that they all rely explicitly on the assumption
that the character array includes a null terminator. If by oversight or error
the null is omitted or overwritten, there&#8217;s very little to keep the C
<B>char</B> array handling functions from manipulating the memory beyond the
limits of the allocated space, sometimes with disastrous results.
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">C++ provides a vast improvement in the
convenience and safety of <B>string</B> objects. For purposes of actual string
handling operations, there are a modest two or three dozen member function
names. It&#8217;s worth your while to become acquainted with these. Each
function is overloaded, so you don&#8217;t have to learn a new <B>string</B>
member function name simply because of small differences in their
parameters.</FONT><A NAME="_Toc519041928"></A><BR></P></DIV>
<A NAME="Heading88"></A><FONT FACE = "Verdana, Tahoma, Arial, Helvetica, Sans"><H3 ALIGN="LEFT">
Appending, inserting and concatenating strings</H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">One of the most valuable and convenient
aspects of C++ strings is that they grow as needed, without intervention on the
part of the programmer. Not only does this make string handling code inherently
more trustworthy, it also almost entirely eliminates a tedious
&#8220;housekeeping&#8221; chore &#8211; keeping track of the bounds of the
storage in which your strings live. For example, if you create a string object
and initialize it with a string of 50 copies of &#8216;X&#8217;, and later store
in it 50 copies of &#8220;Zowie&#8221;, the object itself will reallocate
sufficient storage to accommodate the growth of the data. Perhaps nowhere is
this property more appreciated than when the strings manipulated in your code
change in size, and you don&#8217;t know how big the change is. Appending,
concatenating, and inserting strings often give rise to this circumstance, but
the string member functions <B>append(&#160;)</B> and <B>insert(&#160;)</B>
transparently reallocate storage when a string grows.</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C04:StrSize.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() {
  string bigNews(<font color=#004488>"I saw Elvis in a UFO. "</font>);
  cout &lt;&lt; bigNews &lt;&lt; endl;
  <font color=#009900>// How much data have we actually got?</font>
  cout &lt;&lt; <font color=#004488>"Size = "</font> &lt;&lt; bigNews.size() &lt;&lt; endl;
  <font color=#009900>// How much can we store without reallocating</font>
  cout &lt;&lt; <font color=#004488>"Capacity = "</font> 
    &lt;&lt; bigNews.capacity() &lt;&lt; endl;
  <font color=#009900>// Insert this string in bigNews immediately</font>
  <font color=#009900>// before bigNews[1]</font>
  bigNews.insert(1, <font color=#004488>" thought I "</font>);
  cout &lt;&lt; bigNews &lt;&lt; endl;
  cout &lt;&lt; <font color=#004488>"Size = "</font> &lt;&lt; bigNews.size() &lt;&lt; endl;
  cout &lt;&lt; <font color=#004488>"Capacity = "</font> 
    &lt;&lt; bigNews.capacity() &lt;&lt; endl;
  <font color=#009900>// Make sure that there will be this much space</font>
  bigNews.reserve(500);
  <font color=#009900>// Add this to the end of the string</font>
  bigNews.append(<font color=#004488>"I've been working too hard."</font>);
  cout &lt;&lt; bigNews &lt;&lt; endl;
  cout &lt;&lt; <font color=#004488>"Size = "</font> &lt;&lt; bigNews.size() &lt;&lt; endl;
  cout &lt;&lt; <font color=#004488>"Capacity = "</font> 
    &lt;&lt; bigNews.capacity() &lt;&lt; endl;
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Here is the output:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE>I saw Elvis in a UFO.
Size = 21
Capacity = 31
I thought I saw Elvis in a UFO.
Size = 32
Capacity = 63
I thought I saw Elvis in a UFO. I've been 
working too hard.
Size = 66
Capacity = 511</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">This example demonstrates that even
though you can safely relinquish much of the responsibility for allocating and
managing the memory your <B>string</B>s occupy, C++ <B>string</B>s provide you
with several tools to monitor and manage their size. The <B>size(&#160;)</B>,
<B>resize(&#160;)</B>, <B>capacity(&#160;)</B>, and <B>reserve(&#160;)</B>
member functions can be very useful when its necessary to work back and forth
between data contained in C++ style strings and traditional null terminated C
<B>char</B> arrays. Note the ease with which we changed the size of the storage
allocated to the string.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The exact fashion in which the
<B>string</B> member functions will allocate space for your data is dependent on
the implementation of the library. When one implementation was tested with the
example above, it appeared that reallocations occurred on even word boundaries,
with one byte held back. The architects of the <B>string</B> class have
endeavored to make it possible to mix the use of C <B>char</B> arrays and C++
string objects, so it is likely that figures reported by <B>StrSize.cpp</B> for
capacity reflect that in this particular implementation, a byte is set aside to
easily accommodate the insertion of a null terminator.
</FONT><A NAME="_Toc519041929"></A><BR></P></DIV>
<A NAME="Heading89"></A><FONT FACE = "Verdana, Tahoma, Arial, Helvetica, Sans"><H3 ALIGN="LEFT">
Replacing string characters</H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia"><B>insert(&#160;) </B>is particularly
nice because it absolves you of making sure the insertion of characters in a
string won&#8217;t overrun the storage space or overwrite the characters
immediately following the insertion point. Space grows and existing characters
politely move over to accommodate the new elements. Sometimes, however, this
might not be what you want to happen. If the data in string needs to retain the
ordering of the original characters relative to one another or must be a
specific constant size, use the <B>replace(&#160;)</B> function to overwrite a
particular sequence of characters with another group of characters. There are
quite a number of overloaded versions of <B>replace(&#160;)</B>, but the
simplest one takes three arguments: an integer telling where to start in the
string, an integer telling how many characters to eliminate from the original
string, and the replacement string (which can be a different number of
characters than the eliminated quantity). Here&#8217;s a very simple
example:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C04:StringReplace.cpp</font>
<font color=#009900>// Simple find-and-replace in strings</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 s(<font color=#004488>"A piece of text"</font>);
  string tag(<font color=#004488>"$tag$"</font>);
  s.insert(8, tag + ' ');
  cout &lt;&lt; s &lt;&lt; endl;
  <font color=#0000ff>int</font> start = s.find(tag);
  cout &lt;&lt; <font color=#004488>"start = "</font> &lt;&lt; start &lt;&lt; endl;
  cout &lt;&lt; <font color=#004488>"size = "</font> &lt;&lt; tag.size() &lt;&lt; endl;
  s.replace(start, tag.size(), <font color=#004488>"hello there"</font>);
  cout &lt;&lt; s &lt;&lt; endl;
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The <B>tag</B> is first inserted into
<B>s</B> (notice that the insert happens <I>before</I> the value indicating the
insert point, and that an extra space was added after <B>tag</B>), then it is
found and replaced.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">You should actually check to see if
you&#8217;ve found anything before you perform a <B>replace(&#160;)</B>.<B>
</B>The above example replaces with a <B>char*</B>, but there&#8217;s an
overloaded version that replaces with a <B>string</B>.<B> </B>Here&#8217;s a
more complete demonstration <B>replace(&#160;)</B></FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C04:Replace.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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -