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

📄 chap05.htm

📁 C++编程思想第二版第二卷
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<font color=#009900>//{L} ../TestSuite/Test</font>
#include <font color=#004488>"..</font><font color=#004488>/require.h"</font>
#include &lt;fstream&gt;  
#include &lt;iostream&gt;
<font color=#0000ff>using</font> <font color=#0000ff>namespace</font> std;

<font color=#0000ff>int</font> main() {
  <font color=#0000ff>const</font> <font color=#0000ff>int</font> sz = 100; <font color=#009900>// Buffer size;</font>
  <font color=#0000ff>char</font> buf[sz];
  {
    ifstream in(<font color=#004488>"Strfile.cpp"</font>); <font color=#009900>// Read</font>
    assure(in, <font color=#004488>"Strfile.cpp"</font>); <font color=#009900>// Verify open</font>
    ofstream out(<font color=#004488>"Strfile.out"</font>); <font color=#009900>// Write</font>
    assure(out, <font color=#004488>"Strfile.out"</font>);
    <font color=#0000ff>int</font> i = 1; <font color=#009900>// Line counter</font>

    <font color=#009900>// A less-convenient approach for line input:</font>
    <font color=#0000ff>while</font>(in.get(buf, sz)) { <font color=#009900>// Leaves \n in input</font>
      in.get(); <font color=#009900>// Throw away next character (\n)</font>
      cout &lt;&lt; buf &lt;&lt; endl; <font color=#009900>// Must add \n</font>
      <font color=#009900>// File output just like standard I/O:</font>
      out &lt;&lt; i++ &lt;&lt; <font color=#004488>": "</font> &lt;&lt; buf &lt;&lt; endl;
    }
  } <font color=#009900>// Destructors close in &amp; out</font>

  ifstream in(<font color=#004488>"Strfile.out"</font>);
  assure(in, <font color=#004488>"Strfile.out"</font>);
  <font color=#009900>// More convenient line input:</font>
  <font color=#0000ff>while</font>(in.getline(buf, sz)) { <font color=#009900>// Removes \n</font>
    <font color=#0000ff>char</font>* cp = buf;
    <font color=#0000ff>while</font>(*cp != ':')
      cp++;
    cp += 2; <font color=#009900>// Past ": "</font>
    cout &lt;&lt; cp &lt;&lt; endl; <font color=#009900>// Must still add \n</font>
  }
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The creation of both the <B>ifstream</B>
and <B>ofstream</B> are followed by an <B>assure(&#160;)</B> to guarantee the
file has been successfully opened. Here again the object, used in a situation
where the compiler expects an integral result, produces a value that indicates
success or failure. (To do this, an automatic type conversion member function is
called. These are discussed in Chapter XX.)</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The first <B>while</B> loop demonstrates
the use of two forms of the <B>get(&#160;)</B>
<A NAME="Index260"></A><A NAME="Index261"></A>function. The first gets
characters into a buffer and puts a zero terminator in the buffer when either
<B>sz &#8211; 1</B> characters have been read or the third argument (defaulted
to <B>&#8216;\n&#8217;</B>) is encountered. <B>get(&#160;)</B> leaves the
terminator character in the input stream, so this terminator must be thrown away
via <B>in.get(&#160;)</B> using the form of <B>get(&#160;)</B> with no argument,
which fetches a single byte and returns it as an <B>int</B>. You can also use
the <B>ignore(&#160;)</B> <A NAME="Index262"></A><A NAME="Index263"></A>member
function, which has two defaulted arguments. The first is the number of
characters to throw away, and defaults to one. The second is the character at
which the <B>ignore(&#160;)</B> function quits (after extracting it) and
defaults to EOF.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Next you see two output statements that
look very similar: one to <B>cout </B>and one to the file <B>out</B>. Notice the
convenience here; you don&#8217;t need to worry about what kind of object
you&#8217;re dealing with because the formatting statements work the same with
all <B>ostream</B> <A NAME="Index264"></A>objects. The first one echoes the line
to standard output, and the second writes the line out to the new file and
includes a line number.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">To demonstrate
<B>getline(&#160;)<A NAME="Index265"></A><A NAME="Index266"></A></B>, it&#8217;s
interesting to open the file we just created and strip off the line numbers. To
ensure the file is properly closed before opening it to read, you have two
choices. You can surround the first part of the program in braces to force the
<B>out</B> object out of scope, thus calling the destructor and closing the
file, which is done here. You can also call <B>close(&#160;)</B> for both files;
if you want, you can even reuse the <B>in</B> object by calling the
<B>open(&#160;)</B> member function (you can also create and destroy the object
dynamically on the heap as is in Chapter XX).</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The second <B>while</B> loop shows how
<B>getline(&#160;)</B> removes the terminator character (its third argument,
which defaults to <B>&#8216;\n&#8217;</B>) from the input stream when it&#8217;s
encountered. Although <B>getline(&#160;)</B>, like <B>get(&#160;)</B>, puts a
zero in the buffer, it still doesn&#8217;t insert the terminating
character.</FONT><A NAME="_Toc312373882"></A><A NAME="_Toc519041950"></A><BR></P></DIV>
<A NAME="Heading118"></A><FONT FACE = "Verdana, Tahoma, Arial, Helvetica, Sans"><H3 ALIGN="LEFT">
Open
modes<BR><A NAME="Index267"></A><A NAME="Index268"></A><A NAME="Index269"></A></H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">You can control the way a file is opened
by changing a default argument. The following table shows the flags that control
the mode of the file:</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><TABLE BORDER>
<TR VALIGN="TOP">
<TH WIDTH=92 COLSPAN=1 ROWSPAN=1 VALIGN="TOP">
<DIV ALIGN="LEFT"><P><FONT FACE="Verdana"><B>Flag</B></FONT><BR></P></DIV>
</TH>
<TH WIDTH=176 COLSPAN=1 ROWSPAN=1 VALIGN="TOP">
<DIV ALIGN="LEFT"><P><FONT FACE="Verdana"><B>Function</B></FONT><BR></P></DIV>
</TH>
</TR>
<TR VALIGN="TOP">
<TD>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia"><B>ios::in</B></FONT><BR></P></DIV>
</TD>
<TD>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Opens an input file. Use this as an open
mode for an <B>ofstream</B> to prevent truncating an existing
file.</FONT><BR></P></DIV>
</TD>
</TR>
<TR VALIGN="TOP">
<TD>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia"><B>ios::out</B></FONT><BR></P></DIV>
</TD>
<TD>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Opens an output file. When used for an
<B>ofstream</B> without <B>ios::app</B>, <B>ios::ate</B> or <B>ios::in</B>,
<B>ios::trunc</B> is implied.</FONT><BR></P></DIV>
</TD>
</TR>
<TR VALIGN="TOP">
<TD>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia"><B>ios::app</B></FONT><BR></P></DIV>
</TD>
<TD>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Opens an output file for
appending.</FONT><BR></P></DIV>
</TD>
</TR>
<TR VALIGN="TOP">
<TD>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia"><B>ios::ate</B></FONT><BR></P></DIV>
</TD>
<TD>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Opens an existing file (either input or
output) and seeks the end.</FONT><BR></P></DIV>
</TD>
</TR>
<TR VALIGN="TOP">
<TD>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia"><B>ios::nocreate</B></FONT><BR></P></DIV>
</TD>
<TD>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Opens a file only if it already exists.
(Otherwise it fails.)</FONT><BR></P></DIV>
</TD>
</TR>
<TR VALIGN="TOP">
<TD>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia"><B>ios::noreplace</B></FONT><BR></P></DIV>
</TD>
<TD>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Opens a file only if it does not exist.
(Otherwise it fails.)</FONT><BR></P></DIV>
</TD>
</TR>
<TR VALIGN="TOP">
<TD>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia"><B>ios::trunc</B></FONT><BR></P></DIV>
</TD>
<TD>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Opens a file and deletes the old file, if
it already exists.</FONT><BR></P></DIV>
</TD>
</TR>
<TR VALIGN="TOP">
<TD>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia"><B>ios::binary</B></FONT><BR></P></DIV>
</TD>
<TD>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Opens a file in binary mode. Default is
text mode.</FONT><BR></P></DIV>
</TD>
</TR>
</TABLE></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">These flags can be combined using a
bitwise
<I>or</I>.</FONT><A NAME="_Toc305628666"></A><A NAME="_Toc312373883"></A><A NAME="_Toc519041951"></A><BR></P></DIV>
<A NAME="Heading119"></A><FONT FACE = "Verdana, Tahoma, Arial, Helvetica, Sans"><H2 ALIGN="LEFT">
Iostream buffering<BR><A NAME="Index270"></A><A NAME="Index271"></A></H2></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Whenever you create a new class, you
should endeavor to hide the details of the underlying implementation as possible
from the user of the class. Try to show them only what they need to know and
make the rest <B>private </B>to avoid confusion. Normally when using iostreams
you don&#8217;t know or care where the bytes are being produced or consumed;
indeed, this is different depending on whether you&#8217;re dealing with
standard I/O, files, memory, or some newly created class or
device.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">There comes a time, however, when it
becomes important to be able to send messages to the part of the iostream that
produces and consumes bytes. To provide this part with a common interface and
still hide its underlying implementation, it is abstracted into its own class,
called <B>streambuf<A NAME="Index272"></A></B>. Each iostream object contains a
pointer to some kind of <B>streambuf</B>. (The kind depends on whether it deals
with standard I/O, files, memory, etc.) You can access the <B>streambuf
</B>directly; for example, you can move raw bytes into and out of the
<B>streambuf</B>, without formatting them through the enclosing iostream. This
is accomplished, of course, by calling member functions for the <B>streambuf</B>
object.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Currently, the most important thing for
you to know is that every iostream object contains a pointer to a
<B>streambuf</B> object, and the <B>streambuf</B> has some member functions you
can call if you need to.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">To allow you to access the
<B>streambuf</B>, every iostream object has a member function called
<B>rdbuf(&#160;)<A NAME="Index273"></A><A NAME="Index274"></A></B> that returns
the pointer to the object&#8217;s <B>streambuf</B>. This way you can call any
member function for the underlying <B>streambuf</B>. However, one of the most
interesting things you can do with the <B>streambuf</B> pointer is to connect it
to another iostream object using the <B>&lt;&lt;</B> operator. This drains all
the bytes from your object into the one on the left-hand side of the
<B>&lt;&lt;</B>. This means if you want to move all the bytes from one iostream
to another, you don&#8217;t have to go through the tedium (and potential coding
errors) of reading them one byte or one line at a time. It&#8217;s a much more
elegant approach.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">For example, here&#8217;s a very simple
program that opens a file and sends the contents out to standard output (similar
to the previous example):</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C05:Stype.cpp</font>
<font color=#009900>// Type a file to standard output</font>
<font color=#009900>//{L} ../TestSuite/Test</font>
#include <font color=#004488>"..</font><font color=#004488>/require.h"</font>
#include &lt;fstream&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 + -