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

📄 chap04.htm

📁 C++编程思想第二版第二卷
💻 HTM
📖 第 1 页 / 共 5 页
字号:
    current = s.rfind(';', current);
  }
  <font color=#009900>// Pick up the first word - it's not </font>
  <font color=#009900>// preceded by a delimiter</font>
  strings.push_back(s.substr(0, last - current));
  <font color=#009900>// Print them in the new order:</font>
  <font color=#0000ff>for</font>(<font color=#0000ff>int</font> j = 0; j &lt; strings.size(); j++)
    cout &lt;&lt; strings[j] &lt;&lt; <font color=#004488>" "</font>;
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Here&#8217;s how the output from
<B>Rparse.cpp</B> looks:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE>now.;sense;make;to;going;is;This
This is going to make sense now.</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia"><B>rfind(&#160;)</B> backs through the
string looking for tokens, reporting the array index of matching characters or
<B>string::npos</B> if it is unsuccessful.
</FONT><A NAME="_Toc519041933"></A><BR></P></DIV>
<A NAME="Heading94"></A><FONT FACE = "Verdana, Tahoma, Arial, Helvetica, Sans"><H3 ALIGN="LEFT">
Finding first/last of a set</H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The <B>find_first_of(&#160;)</B> and
<B>find_last_of(&#160;)</B> member functions can be conveniently put to work to
create a little utility that will strip whitespace characters off of both ends
of a string. Notice it doesn&#8217;t touch the original string, but instead
returns a new string:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C04:trim.h</font>
#ifndef TRIM_H
#define TRIM_H
#include &lt;string&gt;
<font color=#009900>// General tool to strip spaces from both ends:</font>
<font color=#0000ff>inline</font> std::string trim(<font color=#0000ff>const</font> std::string&amp; s) {
  <font color=#0000ff>if</font>(s.length() == 0)
    <font color=#0000ff>return</font> s;
  <font color=#0000ff>int</font> b = s.find_first_not_of(<font color=#004488>" \t"</font>);
  <font color=#0000ff>int</font> e = s.find_last_not_of(<font color=#004488>" \t"</font>);
  <font color=#0000ff>if</font>(b == -1) <font color=#009900>// No non-spaces</font>
    <font color=#0000ff>return</font> <font color=#004488>""</font>;
  <font color=#0000ff>return</font> std::string(s, b, e - b + 1);
}
#endif <font color=#009900>// TRIM_H ///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The first test checks for an empty
<B>string</B>; in that case no tests are made and a copy is returned. Notice
that once the end points are found, the <B>string</B> constructor is used to
build a new <B>string</B> from the old one, giving the starting count and the
length. This form also utilizes the &#8220;return value optimization&#8221; (see
the index for more details).</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Testing such a general-purpose tool needs
to be thorough:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C04:TrimTest.cpp</font>
<font color=#009900>//{L} ../TestSuite/Test</font>
#include <font color=#004488>"trim.h"</font>
#include &lt;iostream&gt;
<font color=#0000ff>using</font> <font color=#0000ff>namespace</font> std;

string s[] = {
  <font color=#004488>" \t abcdefghijklmnop \t "</font>,
  <font color=#004488>"abcdefghijklmnop \t "</font>,
  <font color=#004488>" \t abcdefghijklmnop"</font>,
  <font color=#004488>"a"</font>, <font color=#004488>"ab"</font>, <font color=#004488>"abc"</font>, <font color=#004488>"a b c"</font>,
  <font color=#004488>" \t a b c \t "</font>, <font color=#004488>" \t a \t b \t c \t "</font>,
  <font color=#004488>""</font>, <font color=#009900>// Must also test the empty string</font>
};

<font color=#0000ff>void</font> test(string s) {
  cout &lt;&lt; <font color=#004488>"["</font> &lt;&lt; trim(s) &lt;&lt; <font color=#004488>"]"</font> &lt;&lt; endl;
}

<font color=#0000ff>int</font> main() {
  <font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 0; i &lt; <font color=#0000ff>sizeof</font> s / <font color=#0000ff>sizeof</font> *s; i++)
    test(s[i]);
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">In the array of <B>string</B> <B>s</B>,
you can see that the character arrays are automatically converted to
<B>string</B> objects. This array provides cases to check the removal of spaces
and tabs from both ends, as well as ensuring that spaces and tabs do not get
removed from the middle of a
<B>string</B>.</FONT><A NAME="_Toc519041934"></A><BR></P></DIV>
<A NAME="Heading95"></A><FONT FACE = "Verdana, Tahoma, Arial, Helvetica, Sans"><H3 ALIGN="LEFT">
Removing characters from strings</H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">My word processor/page layout program
(Microsoft Word) will save a document in HTML, but it doesn&#8217;t recognize
that the code listings in this book should be tagged with the HTML
&#8220;preformatted&#8221; tag (&lt;PRE&gt;), and it puts paragraph marks
(&lt;P&gt; and &lt;/P&gt;) around every listing line. This means that all the
indentation in the code listings is lost. In addition, Word saves HTML with
reduced font sizes for body text, which makes it hard to read.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">To convert the book to HTML
form</FONT><A NAME="fnB9" HREF="#fn9">[9]</A><FONT FACE="Georgia">, then, the
original output must be reprocessed, watching for the tags that mark the start
and end of code listings, inserting the &lt;PRE&gt; and &lt;/PRE&gt; tags at the
appropriate places, removing all the &lt;P&gt; and &lt;/P&gt; tags within the
listings, and adjusting the font sizes. Removal is accomplished with the
<B>erase(&#160;)</B> member function, but you must correctly determine the
starting and ending points of the substring you wish to erase. Here&#8217;s the
program that reprocesses the generated HTML file:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C04:ReprocessHTML.cpp</font>
<font color=#009900>// Take Word's html output and fix up </font>
<font color=#009900>// the code listings and html tags</font>
#include <font color=#004488>"..</font><font color=#004488>/require.h"</font>
#include &lt;iostream&gt;
#include &lt;fstream&gt;
#include &lt;string&gt;
<font color=#0000ff>using</font> <font color=#0000ff>namespace</font> std;

<font color=#009900>// Produce a new string which is the original</font>
<font color=#009900>// string with the html paragraph break marks</font>
<font color=#009900>// stripped off:</font>
string stripPBreaks(string s) {
  <font color=#0000ff>int</font> br;
  <font color=#0000ff>while</font>((br = s.find(<font color=#004488>"&lt;P&gt;"</font>)) != string::npos)
    s.erase(br, strlen(<font color=#004488>"&lt;P&gt;"</font>));
  <font color=#0000ff>while</font>((br = s.find(<font color=#004488>"&lt;</font><font color=#004488>/P&gt;"</font>)) != string::npos)
    s.erase(br, strlen(<font color=#004488>"&lt;</font><font color=#004488>/P&gt;"</font>));
  <font color=#0000ff>return</font> s;
}

<font color=#009900>// After the beginning of a code listing is</font>
<font color=#009900>// detected, this function cleans up the listing</font>
<font color=#009900>// until the end marker is found. The first line</font>
<font color=#009900>// of the listing is passed in by the caller, </font>
<font color=#009900>// which detects the start marker in the line.</font>
<font color=#0000ff>void</font> fixupCodeListing(istream&amp; in, 
  ostream&amp; out, string&amp; line, <font color=#0000ff>int</font> tag) {
  out &lt;&lt; line.substr(0, tag)
    &lt;&lt; <font color=#004488>"&lt;PRE&gt;"</font> <font color=#009900>// Means "preformatted" in html</font>
    &lt;&lt; stripPBreaks(line.substr(tag)) &lt;&lt; endl;
  string s;
  <font color=#0000ff>while</font>(getline(in, s)) {
    <font color=#0000ff>int</font> endtag = s.find(<font color=#004488>"</font><font color=#004488>/"</font><font color=#004488>"</font><font color=#004488>/"</font><font color=#004488>"</font><font color=#004488>/"</font><font color=#004488>":~"</font>);
    <font color=#0000ff>if</font>(endtag != string::npos) {
      endtag += strlen(<font color=#004488>"</font><font color=#004488>/"</font><font color=#004488>"</font><font color=#004488>/"</font><font color=#004488>"</font><font color=#004488>/"</font><font color=#004488>":~"</font>);
      string before = s.substr(0, endtag);
      string after = s.substr(endtag);
      out &lt;&lt; stripPBreaks(before) &lt;&lt; <font color=#004488>"&lt;</font><font color=#004488>/PRE&gt;"</font> 
        &lt;&lt; after &lt;&lt; endl;
      <font color=#0000ff>return</font>;
    }
    out &lt;&lt; stripPBreaks(s) &lt;&lt; endl;
  }
}

string removals[] = {
  <font color=#004488>"&lt;FONT SIZE=2&gt;"</font>,
  <font color=#004488>"&lt;FONT SIZE=1&gt;"</font>,
  <font color=#004488>"&lt;FONT FACE=\"</font>Times\<font color=#004488>" SIZE=1&gt;"</font>,
  <font color=#004488>"&lt;FONT FACE=\"</font>Times\<font color=#004488>" SIZE=2&gt;"</font>,
  <font color=#004488>"&lt;FONT FACE=\"</font>Courier\<font color=#004488>" SIZE=1&gt;"</font>,
  <font color=#004488>"SIZE=1"</font>, <font color=#009900>// Eliminate all other '1' &amp; '2' size</font>
  <font color=#004488>"SIZE=2"</font>,
};
<font color=#0000ff>const</font> <font color=#0000ff>int</font> rmsz = 
  <font color=#0000ff>sizeof</font>(removals)/<font color=#0000ff>sizeof</font>(*removals);

<font color=#0000ff>int</font> main(<font color=#0000ff>int</font> argc, <font color=#0000ff>char</font>* argv[]) {
  requireArgs(argc, 2);
  ifstream in(argv[1]);
  assure(in, argv[1]);
  ofstream out(argv[2]);
  string line;
  <font color=#0000ff>while</font>(getline(in, line)) {
    <font color=#009900>// The "Body" tag only appears once:</font>
    <font color=#0000ff>if</font>(line.find(<font color=#004488>"&lt;BODY"</font>) != string::npos) {
      out &lt;&lt; <font color=#004488>"&lt;BODY BGCOLOR=\"</font>#FFFFFF\<font color=#004488>" "</font>
      <font color=#004488>"TEXT=\"</font>#000000\<font color=#004488>"&gt;"</font> &lt;&lt; endl;
      <font color=#0000ff>continue</font>; <font color=#009900>// Get next line</font>
    }
    <font color=#009900>// Eliminate each of the removals strings:</font>
    <font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 0; i &lt; rmsz; i++) {
      <font color=#0000ff>int</font> find = line.find(removals[i]);
      <font color=#0000ff>if</font>(find != string::npos)
        line.erase(find, removals[i].size());
    }
    <font color=#0000ff>int</font> tag1 = line.find(<font color=#004488>"</font><font color=#004488>/"</font><font color=#004488>"</font><font color=#004488>/"</font><font color=#004488>":"</font>);
    <font color=#0000ff>int</font> tag2 = line.find(<font color=#004488>"</font><font color=#004488>/"</font><font color=#004488>"*"</font><font color=#004488>":"</font>);
    <font color=#0000ff>if</font>(tag1 != string::npos)
      fixupCodeListing(in, out, line, tag1);
    <font color=#0000ff>else</font> <font color=#0000ff>if</font>(tag2 != string::npos)
      fixupCodeListing(in, out, line, tag2);
    <font color=#0000ff>else</font>
      out &lt;&lt; line &lt;&lt; endl;
  }
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Notice the lines that detect the start
and end listing tags by indicating them with each character in quotes. These
tags are treated in a special way by the logic in the <B>Extractcode.cpp
</B>tool for extracting code listings. To present the code for the tool in the
text of the book, the tag sequence itself must not occur in the listing. This
was accomplished by taking advantage of a C++ preprocessor feature that causes
text strings delimited by adjacent pairs of double quotes to be merged into a
single string during the preprocessor pass of the build. </FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>int</font> tag1 = line.find(<font color=#004488>"</font><font color=#004488>/"</font><font color=#004488>"</font><font color=#004488>/"</font><font color=#004488>":"</font>);</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The effect of the sequence of <B>char</B>
arrays is to produce the starting tag for code listings.</FONT><BR></P></DIV>
<A NAME="Heading96"></A><FONT FACE = "Verdana, Tahoma, Arial, Helvetica, Sans"><H4 ALIGN="LEFT">
Stripping HTML tags</H4></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Sometimes it&#8217;s useful to take an
HTML file and strip its tags so you have something approximating the text that
would be displayed in the Web browser, only as an ASCII text file. The
<B>string</B> class once again comes in handy. The following has some variation
on the theme of the previous example:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C04:HTMLStripper.cpp</font>
<font color=#009900>// Filter to remove html tags and markers</font>
#include <font color=#004488>"..</font><font color=#004488>/require.h"</font>
#include &lt;fstream&gt;
#include &lt;iostream&gt;
#include &lt;string&gt;
<font color=#0000ff>using</font> <font color=#0000ff>namespace</font> std;

string replaceAll(string s, string f, string r) {
  <font color=#0000ff>unsigned</font> <font color=#0000ff>int</font> found = s.find(f);
  <font color=#0000ff>while</font>(found != string::npos) {
    s.replace(found, f.length(), r);
    found = s.find(f);
  }
  <font color=#0000ff>return</font> s;
}

string stripHTMLTags(string s) {
  <font color=#0000ff>while</font>(<font color=#0000ff>true</font>) {
    <font color=#0000ff>unsigned</font> <font color=#0000ff>int</font> left = s.find('&lt;');
    <font color=#0000ff>unsigned</font> <font color=#0000ff>int</font> right = s.find('&gt;');
    <font color=#0000ff>if</font>(left==string::npos || right==string::npos)
      <font color=#0000ff>break</font>;
    s = s.erase(left, right - left + 1);
  }
  s = replaceAll(s, <font color=#004488>"&amp;lt;"</font>, <font color=#004488>"&lt;"</font>);
  s = replaceAll(s, <font color=#004488>"&amp;gt;"</font>, <font color=#004488>"&gt;"</font>);
  s = replaceAll(s, <font c

⌨️ 快捷键说明

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