📄 ch16.htm
字号:
<P><FONT COLOR="#000077"><B>Analysis</B></FONT><FONT COLOR="#000000"><B>:</B></FONT><B>
</B>Lines 7-9 repeat the functionality from the previous example. Lines 12-15 repeat
this again, but this time, on line 14, the fill character is set to asterisks, as
reflected in the output.
<H4 ALIGN="CENTER"><A NAME="Heading47"></A><FONT COLOR="#000077">Set Flags</FONT></H4>
<P>The <TT>iostream</TT> objects keep track of their state by using flags. You can
set these flags by calling <TT>setf()</TT> and passing in one or another of the predefined
enumerated constants.</P>
<DL>
<DD>
<HR>
<FONT COLOR="#000077"><B>New Term:</B></FONT><B> </B>Objects are said to have <I>state
</I>when some or all of their data represents a condition that can change during
the course of the program.
<HR>
</DL>
<P>For example, you can set whether or not to show trailing zeros (so that 20.00
does not become truncated to 20). To turn trailing zeros on, call <TT>setf(ios::showpoint)</TT>.</P>
<P>The enumerated constants are scoped to the <TT>iostream</TT> class (<TT>ios</TT>)
and thus are called with the full qualification <TT>ios::flagname</TT>, such as <TT>ios::showpoint</TT>.</P>
<P>You can turn on the plus sign (<TT>+</TT>) before positive numbers by using <TT>ios::showpos</TT>.
You can change the alignment of the output by using <TT>ios::left</TT>,<TT> ios::right</TT>,
or <TT>ios::internal</TT>.</P>
<P>Finally, you can set the base of the numbers for display by using <TT>ios::dec</TT>
(decimal), <TT>ios::oct</TT> (octal--base eight), or <TT>ios::hex</TT> (hexadecimal--base
sixteen). These flags can also be concatenated into the insertion operator. Listing
16.14 illustrates these settings. As a bonus, Listing 16.14 also introduces the <TT>setw</TT>
manipulator, which sets the width but can also be concatenated with the insertion
operator.</P>
<P><A NAME="Heading48"></A><FONT SIZE="4" COLOR="#000077"><B>Listing 16.14. Using
setf.</B></FONT></P>
<PRE><FONT COLOR="#0066FF">1: // Listing 16.14 - Using setf
2: #include <iostream.h>
3: #include <iomanip.h>
4:
5: int main()
6: {
7: const int number = 185;
8: cout << "The number is " << number << endl;
9:
10: cout << "The number is " << hex << number << endl;
11:
12: cout.setf(ios::showbase);
13: cout << "The number is " << hex << number << endl;
14:
15: cout << "The number is " ;
16: cout.width(10);
17: cout << hex << number << endl;
18:
19: cout << "The number is " ;
20: cout.width(10);
21: cout.setf(ios::left);
22: cout << hex << number << endl;
23:
24: cout << "The number is " ;
25: cout.width(10);
26: cout.setf(ios::internal);
27: cout << hex << number << endl;
28:
29: cout << "The number is:" << setw(10) << hex << number << endl;
30: return 0;
<TT>31: }</TT></FONT>
<FONT COLOR="#0066FF">
Output: The number is 185
The number is b9
The number is 0xb9
The number is 0xb9
The number is 0xb9
The number is 0x b9
The number is:0x b9</FONT></PRE>
<P><FONT COLOR="#000077"><B>Analysis</B></FONT><FONT COLOR="#000000"><B>:</B></FONT><B>
</B>On line 7, the constant <TT>int</TT> <TT>number</TT> is initialized to the value
<TT>185</TT>. This is displayed on line 8.</P>
<P>The value is displayed again on line 10, but this time the manipulator <TT>hex</TT>
is concatenated, causing the value to be displayed in hexadecimal as <TT>b9</TT>.
(b=11; 11*16=176+9=185).</P>
<P>On line 12, the flag <TT>showbase</TT> is set. This causes the prefix <TT>0x</TT>
to be added to all hexadecimal numbers, as reflected in the output.</P>
<P>On line 16, the width is set to <TT>10</TT>, and the value is pushed to the extreme
right. On line 20, the width is again set to <TT>10</TT>, but this time the alignment
is set to the left, and the number is again printed flush left.</P>
<P>On line 25, once again the width is set to <TT>10</TT>, but this time the alignment
is internal. Thus the <TT>0x</TT> is printed flush left, but the value, <TT>b9</TT>,
is printed flush right.</P>
<P>Finally, on line 29, the concatenation operator <TT>setw()</TT> is used to set
the width to <TT>10</TT>, and the value is printed again.
<H3 ALIGN="CENTER"><A NAME="Heading49"></A><FONT COLOR="#000077">Streams Versus the
printf() Function</FONT></H3>
<P>Most C++ implementations also provide the standard C I/O libraries, including
the <TT>printf()</TT> statement. Although <TT>printf()</TT> is in some ways easier
to use than <TT>cout</TT>, it is far less desirable.</P>
<P><TT>printf()</TT> does not provide type safety, so it is easy to inadvertently
tell it to display an integer as if it was a character and vice versa. <TT>printf()</TT>
also does not support classes, and so it is not possible to teach it how to print
your class data; you must feed each class member to <TT>printf()</TT> one by one.</P>
<P>On the other hand, <TT>printf()</TT> does make formatting much easier, because
you can put the formatting characters directly into the <TT>printf()</TT> statement.
Because <TT>printf()</TT> has its uses and many programmers still make extensive
use of it, this section will briefly review its use.</P>
<P>To use <TT>printf()</TT>, be sure to include the <TT>STDIO.H</TT> header file.
In its simplest form, <TT>printf()</TT> takes a formatting string as its first parameter
and then a series of values as its remaining parameters.</P>
<P>The formatting string is a quoted string of text and conversion specifiers. All
conversion specifiers must begin with the percent symbol (<TT>%</TT>). The common
conversion specifiers are presented in Table 16.1. <BR>
<BR>
<FONT SIZE="4"><B>Table 16.1. The Common Conversion Specifiers</B></FONT>.
<TABLE BORDER="0" WIDTH="221">
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT"><B><I>Specifier</I></B></TD>
<TD ALIGN="LEFT"><B><I>Used For</I></B></TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT"><TT>%s</TT></TD>
<TD ALIGN="LEFT">strings</TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT"><TT>%d</TT></TD>
<TD ALIGN="LEFT">integers</TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT"><TT>%l</TT></TD>
<TD ALIGN="LEFT"><TT>long</TT> integer</TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT"><TT>%ld</TT></TD>
<TD ALIGN="LEFT"><TT>long</TT> integers</TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT"><TT>%f</TT></TD>
<TD ALIGN="LEFT"><TT>float</TT></TD>
</TR>
</TABLE>
<BR>
<BR>
Each of the conversion specifiers can also provide a width statement and a precision
statement, expressed as a <TT>float</TT>, where the digits to the left of the decimal
are used for the total width, and the digits to the right of the decimal provide
the precision for <TT>float</TT>s. Thus, <TT>%5d</TT> is the specifier for a five-digit-wide
integer, and <TT>%15.5f</TT> is the specifier for a 15-digit-wide <TT>float</TT>,
of which the final five digits are dedicated to the decimal portion. Listing 16.15
illustrates various uses of <TT>printf()</TT>.</P>
<P><A NAME="Heading50"></A><FONT SIZE="4" COLOR="#000077"><B>Listing 16.15. Printing
with printf().</B></FONT></P>
<PRE><FONT COLOR="#0066FF">1: #include <stdio.h>
2: int main()
3: {
4: printf("%s","hello world\n");
5:
6: char *phrase = "Hello again!\n";
7: printf("%s",phrase);
8:
9: int x = 5;
10: printf("%d\n",x);
11:
12: char *phraseTwo = "Here's some values: ";
13: char *phraseThree = " and also these: ";
14: int y = 7, z = 35;
15: long longVar = 98456;
16: float floatVar = 8.8;
17:
18: printf("%s %d %d %s %ld %f\n",phraseTwo,y,z,phraseThree,longVar,floatVar);
19:
20: char *phraseFour = "Formatted: ";
21: printf("%s %5d %10d %10.5f\n",phraseFour,y,z,floatVar);
22: return 0;
<TT>23: }</TT></FONT>
<FONT COLOR="#0066FF">
Output: hello world
Hello again!
5
Here's some values: 7 35 and also these: 98456 8.800000
Formatted: 7 35 8.800000
</FONT></PRE>
<P><FONT COLOR="#000077"><B>Analysis: </B></FONT>The first <TT>printf()</TT> statement,
on line 4, uses the standard form: the term <TT>printf</TT>, followed by a quoted
string with a conversion specifier (in this case <TT>%s</TT>), followed by a value
to insert into the conversion specifier.</P>
<P>The <TT>%s</TT> indicates that this is a string, and the value for the string
is, in this case, the quoted string <TT>"hello world".</TT></P>
<P>The second <TT>printf()</TT> statement is just like the first, but this time a
<TT>char</TT> pointer is used, rather than quoting the string right in place in the
<TT>printf()</TT> statement.</P>
<P>The third <TT>printf()</TT>, on line 10, uses the integer conversion specifier,
and for its value the integer variable <TT>x</TT>. The fourth <TT>printf()</TT> statement,
on line 18, is more complex. Here six values are concatenated. Each conversion specifier
is supplied, and then the values are provided, separated by commas.</P>
<P>Finally, on line 21, format specifications are used to specify width and precision.
As you can see, all of this is somewhat easier than using manipulators.</P>
<P>As stated previously, however, the limitation here is that there is no type checking
and <TT>printf()</TT> cannot be declared a friend or member function of a class.
So if you want to print the various member data of a class, you must feed each accessor
method to the <TT>printf()</TT> statement explicitly.
<CENTER>
<H3><A NAME="Heading51"></A><FONT COLOR="#000077">File Input and Output</FONT></H3>
</CENTER>
<P>Streams provide a uniform way of dealing with data coming from the keyboard or
the hard disk and going out to the screen or hard disk. In either case, you can use
the insertion and extraction operators or the other related functions and manipulators.
To open and close files, you create <TT>ifstream</TT> and <TT>ofstream</TT> objects
as described in the next few sections.
<CENTER>
<H3><A NAME="Heading52"></A><FONT COLOR="#000077">ofstream</FONT></H3>
</CENTER>
<P>The particular objects used to read from or write to files are called <TT>ofstream</TT>
objects. These are derived from the <TT>iostream</TT> objects you've been using so
far.</P>
<P>To get started with writing to a file, you must first create an <TT>ofstream</TT>
object, and then associate that object with a particular file on your disk. To use
<TT>ofstream</TT> objects, you must be sure to include <TT>fstream.h</TT> in your
program.
<BLOCKQUOTE>
<P>
<HR>
<FONT COLOR="#000077"><B>NOTE:</B></FONT><B> </B>Because <TT>fstream.h</TT> includes
<TT>iostream.h</TT>, there is no need for you to include <TT>iostream</TT> explicitly.
<HR>
</BLOCKQUOTE>
<CENTER>
<H4><A NAME="Heading53"></A><FONT COLOR="#000077">Condition States</FONT></H4>
</CENTER>
<P>The <TT>iostream</TT> objects maintain flags that report on the state of your
input and output. You can check each of these flags using the Boolean functions <TT>eof()</TT>,
<TT>bad()</TT>, <TT>fail()</TT>, and <TT>good()</TT>. The function <TT>eof()</TT>
returns true if the <TT>iostream</TT> object has encountered EOF, end of file. The
function <TT>bad()</TT> returns <TT>TRUE</TT> if you attempt an invalid operation.
The function <TT>fail()</TT> returns <TT>TRUE</TT> anytime <TT>bad()</TT> is true
or an operation fails. Finally, the function <TT>good()</TT> returns <TT>TRUE</TT>
anytime all three of the other functions are <TT>FALSE</TT>.
<CENTER>
<H4><A NAME="Heading54"></A><FONT COLOR="#000077">Opening Files for Input and Output</FONT></H4>
</CENTER>
<P>To open the file <TT>myfile.cpp</TT> with an <TT>ofstream</TT> object, declare
an instance of an <TT>ofstream</TT> object and pass in the filename as a parameter:</P>
<PRE><FONT COLOR="#0066FF">ofstream fout("myfile.cpp");
</FONT></PRE>
<P>Opening this file for input works exactly the same way, except it uses an <TT>ifstream</TT>
object:</P>
<PRE><FONT COLOR="#0066FF">ifstream fin("myfile.cpp");
</FONT></PRE>
<P>Note that <TT>fout</TT> and <TT>fin</TT> are names you assign; here <TT>fout</TT>
has been used to reflect its similarity to <TT>cout</TT>, and <TT>fin</TT> has been
used to reflect its similarity to <TT>cin</TT>.</P>
<P>One important file stream function that you will need right away is <TT>close()</TT>.
Every file stream object you create opens a file for either reading or writing (or
both). It is important to <TT>close()</TT> the file after you finish reading or writing;
this ensures that the file won't be corrupted and that the data you've written is
flushed to the disk.</P>
<P>Once the stream objects are associated with files, they can be used like any other
stream objects. Listing 16.16 illustrates this.</P>
<P><A NAME="Heading55"></A><FONT SIZE="4" COLOR="#000077"><B>Listing 16.16. Openi
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -