2012年2月20日 星期一

C++ Input/Output and File I/O


Input / Output Classes


Class/Template Descriptions

ios_base    class that serves as a base for all stream classes. Contains stream state and format flags.

basic_ios<>    class template derived from ios_base<>. Virtual base for stream classes. Contains a pointer to the stream buffer, functions for stream state and error indications.

ios    basic_ios class for char type
wios    basic_ios class for wchar type

basic_istream<>    class template derived from basic_ios<>. Defines streams used for input.

istream    basic_istream class for char type
wistream    basic_istream class for wchar type

basic_ostream<>    class template derived from basic_ios<>. Defines streams used for output.

ostream    basic_ostream class for char type
wostream    basic_ostream class for wchar type

basic_iostream<>    class template derived from both basic_istream<> and basic_ostream<>. Defines streams used for both input and output.

ostream    basic_iostream class for char type
wostream    basic_iostream class for wchar type

basic_streambuf<>    class template used to define interface to all stream types. Performs the actual reading and writing to/from streams.

streambuf    basic_streambuf class used to handle char type data.
wstreambuf    basic_streambuf class used to handle wchar type data.

ios_base class

typedefs

typedef T1 fmtflags;                T1, T2 are integer types (int, enum, …)
typedef T2 iostate;

constants
Format flag constants
These constants are used to assign a value to a fmtflags value. They represent formatting/parsing specifications for a stream.

boolalpha    reads or displays "true" or "false" for bool values instead of "1" or "0".
dec    reads or displays integer input/output as a decimal number.
fixed    displays floating point numbers in decimal format.
hex    reads or displays integer input/output as a hexadecimal number.
internal    displays octal, hexadecimal, and scientific numbers in internal format.
left    left justifies output in a field.
oct    reads or displays integer input/output as an octal number.
right    right justifies output in a field.
scientific    displays floating point numbers in scientific (exponential) format.
showbase    displays a number base prefix for integer output (0x or 0X for hex and 0 for octal)
showpoint    displays a decimal point in floating point numeric output.
showpos    displays a + sign for positive numeric output.
skipws    skips leading whitespace before >> operations.
unitbuf    flushes output stream after each insertion.
uppercase    displays hexadecimal output and the e of scientific format in uppercase.

adjustfield    group (bitwise or) of three flags :  left, right, and internal.
basefield    group (bitwise or) of three flags :  hex, oct, and dec.
floatfield    group (bitwise or) of two flags :  fixed and scientific.

Stream state constants
These constants are used to assign a value to an iostate value. They represent the state of a stream.

badbit    is set if a stream is corrupted.
eofbit    is set if the EOF has been read.
failbit    is set if an I/O operation fails.
goodbit    is set if a stream is OK, no other bits set.

Some ios_base member functions

fmtflags flags() const;        returns the stream's fmtflags settings

fmtflags flags(fmtflags value);    sets the streams fmtflags.  Note:  clears any other flags already set.

fmtflags setf(fmtflags value);    sets the streams fmtflags.  Note:  does not clear other flags already set.

fmtflags setf(fmtflags val, fmtflags mask);    first clears the mask settings, then sets the stream's fmtflags. Note:  does not clear other flags already set.

void unsetf(fmtflags value);    clears the fmtflags values(s).

streamsize precision() const;    returns the stream's precision setting for floating point values. Note:  precision setting is the number of decimal places if fixed or scientific is set.  If neither is set, the precision represents the number of significant digits. In either case, the value is automatically rounded to the precision setting.

streamsize precision(streamsize size);    sets the stream's precision.  See note above.

streamsize width() const;    returns the stream's field width that applies to the next output value.

streamsize width(streamsize size);    sets the stream's minimum field width that applies only to the next output value. The width applies to both numeric and char data.

Some basic_ios member functions

The ios class is a typedef for the instantiation of the basic_ios template of type char.

char_type fill() const;    returns  the fill character assigned to a stream. This character is used to pad a field whose width is more than the number of characters needed to display a value.

char_type fill(char_type ch);    sets the fill characted assigned to a stream.

bool operator!() const;        returns fail().

bool bad() const;    returns true if the stream's badbit is set. The bad() function indicates a corrupted stream.

void clear(iostream state=goodbit);    sets the iostate (by default to goodbit).

bool eof() const;    returns true if the eofbit is set (the stream's EOF has been read).

bool fail() const;    returns true if the stream's failbit or badbit is set. Use the fail() function to check to see if a file is successfully opened.

bool good() const;    returns true if the stream's goodbit is set.

iostate rdstate() const;    returns a streams iostate value.

Some basic_istream member functions

The istream class is a typedef for the instantiation of the basic_istream template of type char.

streamsize gcount() const;    returns the number of characters read by the last input operation

int get();    reads and returns the next character available in a stream. Returns EOF if no character is available.

istream specific functions

istream& get(char& ch);    reads the next char and assignes it to ch.  Returns the "current" istream.

istream& get(char* buf, streamsize n);    reads n-1 bytes and stores them in buf.  A newline(\n) will terminate the read. In that case, the newline is not read and not stored.  The char data in buf is null-terminated.

istream& get(char* buf, streamsize n, char deliminator);   
reads at most n-1 bytes and stores them in buf.  If the deliminator is encountered, the read ends.  The deliminator is not read and not stored. The char data in buf is null-terminated.

istream& getline(char* buf, streamsize n);    reads n-1 bytes and stores them in buf.  A newline(\n) will terminate the read.  In that case, the newline is read, but not stored. The char data in buf is null-terminated. The newline (\n) is considered the delimiter for this function.  See warning in next paragraph.

istream& getline(char* buf,streamsize n,char deliminator);
    reads at most n-1 bytes and stores them in buf. If the deliminator is encountered, the read ends. The deliminator is read and not stored.  The char data in buf is null-terminated. 

Warning:  If the delimiter is not read, it is considered an error. The failbit is set, even though the stream data is stored in buf. This warning does not apply to the get() function.

istream& ignore(streamsize n=1, int_type deliminator=EOF);
    extracts and discards n char or extracts until deliminator is read.

int_type peek();    returns the next available char. Does not increment the current get pointer.


istream& putback(char ch);    inserts the char ch into the input stream at the current get pointer position-1. Moves the current get pointer position back 1 byte.

istream& read(char* buf, streamsize n);    reads n bytes into buf.  buf is not null terminated.

streamsize readsome(char* buf, streamsize n);   
reads n bytes into buf.  buf is not null terminated. Returns the number of characters read. The difference between read() and readsome() is that readsome() does not set the failbit if it cannot read n characters (if it encounters EOF before the read is complete).

istream& unget();    inserts the last char read into the input stream at its original position.

Some basic_ostream member functions

The ostream class is a typedef for the instantiation of the basic_ostream template of type char.

ostream& flush();    writes any data in the output buffer to the output stream.
ostream specific functions

ostream& put(char ch);    writes ch to the output stream.

ostream& write(char* buf, streamsize n);    writes n bytes of char starting from the address buf into the output stream. 

Example 8-1 – ios_base fmtflags

This example demonstrates the ios_base member, fmtflags.

The following header file, fmtflags.h, will be used in the next few examples:

1      // File: fmtflags.h
2     
3      #ifndef FMTFLAGS_H
4      #define FMTFLAGS_H
5     
6      #include <iostream>
7      using namespace std;
8     
9      void show_fmtflags(ios_base& stream) {
10          if (&stream == &cout) cout << "cout ";
11          if (&stream == &cerr) cout << "cerr ";
12          if (&stream == &clog) cout << "clog ";
13          if (&stream == &cin) cout << "cin ";
14          cout << "ios_base::fmtflags set: ";
15          if (stream.flags() & ios::boolalpha) cout << "boolalpha ";
16          if (stream.flags() & ios::dec) cout << "dec ";
17          if (stream.flags() & ios::fixed) cout << "fixed ";
18          if (stream.flags() & ios::hex) cout << "hex ";
19          if (stream.flags() & ios::internal) cout << "internal ";
20          if (stream.flags() & ios::left) cout << "left ";
21          if (stream.flags() & ios::oct) cout << "oct ";
22          if (stream.flags() & ios::right) cout << "right ";
23          if (stream.flags() & ios::scientific) cout << "scientific ";
24          if (stream.flags() & ios::showbase) cout << "showbase ";
25          if (stream.flags() & ios::showpoint) cout << "showpoint ";
26          if (stream.flags() & ios::showpos) cout << "showpos ";
27          if (stream.flags() & ios::skipws) cout << "skipws ";
28          if (stream.flags() & ios::unitbuf) cout << "unitbuf ";
29          if (stream.flags() & ios::uppercase) cout << "uppercase ";
30          cout << endl;
31      }
32     
33      #endif


1      // File: ex8-1.cpp - ios::fmtflags
2     
3      #include "fmtflags.h"
4     
5      int main()
6      {
7          // save the default fmtflags settings for cout
8          ios::fmtflags cout_flags = cout.flags();
9     
10          // print the default cout fmtflags settings value
11          cout << cout_flags <<endl;
12     
13          // display the default fmtflags values for cout, cin, cerr, clog
14          show_fmtflags(cout);
15          show_fmtflags(cin);
16          show_fmtflags(cerr);
17          show_fmtflags(clog);
18         
19          // turn on hex for cout
20          cout.flags(ios::hex);
21          // display the fmtflags settings for cout
22          show_fmtflags(cout);
23          // print some numbers
24          cout << 12 << ' ' << 123 << ' ' << 1234 << ' ' << 12345 << endl;
25     
26          // turn on hex and showbase for cout
27          cout.flags(ios::hex|ios::showbase);
28          show_fmtflags(cout);
29          cout << 12 << ' ' << 123 << ' ' << 1234 << ' ' << 12345 << endl;
30     
31          // turn on hex, showbase, and uppercase for cout
32          cout.flags(ios::hex|ios::showbase|ios::uppercase);
33          show_fmtflags(cout);
34          cout << 12 << ' ' << 123 << ' ' << 1234 << ' ' << 12345 << endl;
35     
36          // turn on octal for cout
37          cout.flags(ios::oct);
38          show_fmtflags(cout);
39          cout << 12 << ' ' << 123 << ' ' << 1234 << ' ' << 12345 << endl;
40     
41          // turn on octal and showbase for cout
42          cout.flags(ios::oct|ios::showbase);
43          show_fmtflags(cout);
44          cout << 12 << ' ' << 123 << ' ' << 1234 << ' ' << 12345 << endl;
45     
46          // reset cout's flags back to the default settings
47          cout.flags(cout_flags);
48          show_fmtflags(cout);
49          cout << 12 << ' ' << 123 << ' ' << 1234 << ' ' << 12345 << endl;
50     
51          // print out the value for each of the fmtflags constants
52          cout << "ios::boolalpha=" <<ios::boolalpha << endl;
53          cout << "ios::dec=" << ios::dec << endl;
54          cout << "ios::fixed=" << ios::fixed << endl;
55          cout << "ios::hex=" << ios::hex << endl;
56          cout << "ios::internal=" << ios::internal << endl;
57          cout << "ios::left=" << ios::left << endl;
58          cout << "ios::oct=" << ios::oct << endl;
59          cout << "ios::right=" << ios::right << endl;
60          cout << "ios::scientific=" << ios::scientific << endl;
61          cout << "ios::showbase=" << ios::showbase << endl;
62          cout << "ios::showpoint=" << ios::showpoint << endl;
63          cout << "ios::showpos=" << ios::showpos << endl;
64          cout << "ios::skipws=" << ios::skipws << endl;
65          cout << "ios::unitbuf=" << ios::unitbuf << endl;
66          cout << "ios::uppercase=" << ios::uppercase << endl;
67          return 0;
68      }


******  Output (GNU ver. 4.32) ******

4098                                (11)
cout ios_base::fmtflags set: dec skipws                     (14)
cin ios_base::fmtflags set: dec skipws                     (15)
cerr ios_base::fmtflags set: unitbuf                     (16)
clog ios_base::fmtflags set: dec skipws                     (17)
cout ios_base::fmtflags set: hex                        (22)
c 7b 4d2 3039                            (24)
cout ios_base::fmtflags set: hex showbase                     (28)
0xc 0x7b 0x4d2 0x3039                        (29)
cout ios_base::fmtflags set: hex showbase uppercase                 (33)
0XC 0X7B 0X4D2 0X3039                        (34)
cout ios_base::fmtflags set: oct                        (38)
14 173 2322 30071                            (39)
cout ios_base::fmtflags set: oct showbase                    (43)
014 0173 02322 030071                        (44)
cout ios_base::fmtflags set: dec skipws                     (48)
12 123 1234 12345                            (49)
ios::boolalpha=1                            (52)
ios::dec=2                                (53)
ios::fixed=4                            (54)
ios::hex=8                                (55)
ios::internal=16                            (56)
ios::left=32                                (57)
ios::oct=64                                (58)
ios::right=128                            (59)
ios::scientific=256                            (60)
ios::showbase=512                            (61)
ios::showpoint=1024                            (62)
ios::showpos=2048                            (63)
ios::skipws=4096                            (64)
ios::unitbuf=8192                            (65)
ios::uppercase=16384                            (66)


******  Output (MS Visual C++ 2008) ******

513                                (11)
cout ios_base::fmtflags set: dec skipws                    (14)
cin ios_base::fmtflags set: dec skipws                    (15)
cerr ios_base::fmtflags set: dec skipws unitbuf                (16)
clog ios_base::fmtflags set: dec skipws                    (17)
cout ios_base::fmtflags set: hex                        (22)
c 7b 4d2 3039                            (24)
cout ios_base::fmtflags set: hex showbase                    (28)
0xc 0x7b 0x4d2 0x3039                        (29)
cout ios_base::fmtflags set: hex showbase uppercase                (33)
0XC 0X7B 0X4D2 0X3039                        (34)
cout ios_base::fmtflags set: oct                        (38)
14 173 2322 30071                            (39)
cout ios_base::fmtflags set: oct showbase                    (43)
014 0173 02322 030071                        (44)
cout ios_base::fmtflags set: dec skipws                    (48)
12 123 1234 12345                            (49)
ios::boolalpha=16384                            (52)
ios::dec=512                            (53)
ios::fixed=8192                            (54)
ios::hex=2048                            (55)
ios::internal=256                            (56)
ios::left=64                                (57)
ios::oct=1024                            (58)
ios::right=128                            (59)
ios::scientific=4096                            (60)
ios::showbase=8                            (61)
ios::showpoint=16                            (62)
ios::showpos=32                            (63)
ios::skipws=1                            (64)
ios::unitbuf=2                            (65)
ios::uppercase=4                            (66)

Example 8-2 – ios_base member functions

This examples demonstrates some of the ios_base member functions.

1      // File: ex8-2.cpp - ios_base member functions
2     
3      #include "fmtflags.h"
4     
5      int main()
6      {
7          // Display cout's default width, fill, and precision settings
8          cout << "cout.width()=" << cout.width() <<endl;
9          cout << "cout.fill()=" << cout.fill() << ' ' << (int) cout.fill() << endl;
10          cout << "cout.precision()=" << cout.precision() <<endl;
11     
12          // Display cin's default width, fill, and precision settings
13          cout << "cin.width()=" << cin.width() <<endl;
14          cout << "cin.fill()=" << cin.fill() << ' ' << (int) cin.fill() << endl;
15          cout << "cin.precision()=" << cin.precision() <<endl;
16     
17          // Display cerr's default width, fill, and precision settings
18          cout << "cerr.width()=" << cerr.width() <<endl;
19          cout << "cerr.fill()=" << cerr.fill() << ' ' << (int) cerr.fill() << endl;
20          cout << "cerr.precision()=" << cerr.precision() <<endl;
21     
22          // Demonstrate the ios_base::width() function
23          cout << 1 << 2 << 3 << endl;
24          cout.width(5);
25          cout << 1 << 2 << 3 << endl;
26     
27          // Demonstrate the width() function for char data
28          cout.width(5);
29          cout << 'a' << 'b' << 'c' << endl;
30          cout.width(5);
31          cout << "a" << "b" << "c" << endl;
32     
33          // What happens when a value's length exceeds the width setting
34          cout.width(3);
35          cout << 123456789 << '|' <<"hey\n";
36     
37          // width and left justification
38          cout.setf(ios::left,ios::adjustfield);
39          cout.width(5);
40          cout << 1 << 2 << 3 << endl;
41     
42          // Demonstrate fill()
43          cout.fill('$');   
44          cout.width(10);
45          cout << 1 << '|' << 1 << endl;
46     
47          // Set precision to 4
48          cout.precision(4);
49          cout.width(10);
50          cout << 123.45678 << '|' << 1234567.8 << '|' << 1.2345678 << '|' << 12345678 << endl;
51     
52          // precision set to 4 and fixed flag set
53          cout.setf(ios::fixed,ios::floatfield);
54          cout.width(10);
55          cout << 123.45678 << '|' << 1234567.8 << '|' << 1.2345678 << '|' << 12345678 << endl;
56     
57          // Any difference between float and double?
58          float f = 314.f;
59          cout << f << '|' << 314. << endl;
60     
61          // Turn off fixed setting
62          cout.unsetf(ios::fixed);
63          cout << f << '|' << 314. << endl;
64     
65          // Turn on showpoint
66          cout.setf(ios::showpoint);
67          cout << f << '|' << 314. << endl;
68     
69          // Turn on fixed
70          cout.setf(ios::fixed,ios::floatfield);
71          cout << 123.45678 << '|' << 1234567.8 << '|' << 1.2345678 << '|' << 12345678 << endl;
72     
73          // Clear the flags for cout and turn on hex for cin
74          cout.flags(ios_base::fmtflags(0));
75          cin.setf(ios::hex|ios::basefield);
76          cout.width(35);
77          cout << "Enter a hexadecimal number => ";
78          int Hex;
79          cin >> Hex;
80     
81          // Display the Hex value in decimal and hex
82          cout << "Hex=" << Hex << '|' << hex << Hex << endl;
83     
84          // Check the format flags for cin and cout
85          show_fmtflags(cin);
86          show_fmtflags(cout);
87     
88          // Turn on hex, the right way
89          cin.setf(ios::hex,ios::basefield);
90          cout << "Try again, dummy => ";
91          cin >> Hex;
92          cout << Hex << endl;
93     
94          // Is there a problem with cin
95          cout << "cin.rdstate=" << cin.rdstate() << endl;
96     
97          // What are the format flag settings for cin and cout
98          show_fmtflags(cin);
99          show_fmtflags(cout);
100     
101          // Fix the problem with cin
102          cin.clear();
103          cout << "cin.rdstate=" << cin.rdstate() << endl;
104     
105          // Clear the input buffer
106          cin.ignore(50,'\n');
107     
108          // Try again for the Hex input
109          cout << "Ok, get it right this time => ";
110          cin >> Hex;
111          cout << Hex << endl;
112     
113          return 0;
114      }


******  Output (MS Visual C++ 2008)  ******   

cout.width()=0
cout.fill()=  32
cout.precision()=6
cin.width()=0
cin.fill()=  32
cin.precision()=6
cerr.width()=0
cerr.fill()=  32
cerr.precision()=6
123
    123
    abc
    abc
123456789|hey
1    23
1$$$$$$$$$|1
123.5$$$$$|1.235e+006|1.235|12345678
123.4568$$|1234567.8000|1.2346|12345678
314.0000|314.0000
314|314
314.0|314.0
123.4568|1234567.8000|1.2346|12345678
$$$$$Enter a hexadecimal number => abc
Hex=-858993460|cccccccc
cin ios_base::fmtflags set: dec hex oct skipws
cout ios_base::fmtflags set: hex
Try again, dummy => cccccccc
cin.rdstate=2
cin ios_base::fmtflags set: hex skipws
cout ios_base::fmtflags set: hex
cin.rdstate=0
Ok, get it right this time => abc
abc

******  Output (GNU ver. 4.32b) ******

cout.width()=0
cout.fill()=  32
cout.precision()=6
cin.width()=0
cin.fill()=  32
cin.precision()=6
cerr.width()=0
cerr.fill()=  32
cerr.precision()=6
123
    123
    abc
    abc
123456789|hey
1    23
1$$$$$$$$$|1
123.5$$$$$|1.235e+06|1.235|12345678
123.4568$$|1234567.8000|1.2346|12345678
314.0000|314.0000
314|314
314.0|314.0
123.4568|1234567.8000|1.2346|12345678
$$$$$Enter a hexadecimal number => abc
Hex=4197696|400d40
cin ios_base::fmtflags set: dec hex oct skipws
cout ios_base::fmtflags set: hex
Try again, dummy => 400d40
cin.rdstate=4
cin ios_base::fmtflags set: hex skipws
cout ios_base::fmtflags set: hex
cin.rdstate=0
Ok, get it right this time => abc
abc

What happened to the output on Line 88?

The error was actually made in line 81, cin.setf(ios::hex|ios::basefield);. We want cin.setf(ios::hex,ios::basefield) here. By using the | we turn on the hex, dec, and oct fmtflags.

Example 8-3 – istream member functions

1      #include <iostream>
2      using namespace std;
3     
4      int main()
5      {
6          char temp[80], ch;
7     
8          cout << "Enter something => ";
9     
10          // Get the first 6 bytes of the input buffer
11          cin.get(temp,7);
12          cout << "temp=" << temp << endl;
13     
14          // Get the next 7 bytes of the input buffer
15          cin.get(temp,8);
16          cout << "temp=" << temp << endl;
17     
18          // Get the next bytes from the input buffer
19          cin.get(ch);
20          cout << "ch=" << ch << endl;
21     
22          // Get the rest of the input buffer until '\n' is read
23          while (cin.get(ch) && ch != '\n') {
24              cout << ch;
25          }
26          cout << endl;
27     
28          cout << "Enter something else => ";
29          // Get some more data from the input buffer up to 'v'
30          cin.getline(temp,sizeof(temp),'v');
31          cout << "temp=" << temp << endl;
32     
33          // Read 6 more bytes from the input buffer
34          cin.getline(temp,7);
35          cout << "temp=" << temp << endl;
36     
37          // Read 1 more byte from the input buffer
38          cin.get(ch);
39          cout << "ch=" << ch << endl;        // What happened here?
40     
41          // Look at the next byte in the input buffer
42          cout << "cin.peek()=" << cin.peek() << endl;
43     
44          // What is the state of cin
45          cout << "cin.rdstate()=" << cin.rdstate() << endl;
46     
47          // Clear the state of cin
48          cin.clear();
49     
50          // Read 1 byte from the input buffer
51          cin.get(ch);
52          cout << "ch=" << ch << endl;
53     
54          // Write the last byte read back into the input buffer
55          cin.unget();
56     
57          cin.putback('X');
58          cin.getline(temp,sizeof(temp));
59          cout << "temp=" << temp << endl;
60     
61          cout << "Enter some more => ";   
62          cin.read(temp,6);
63          cout << "cin.gcount()=" << cin.gcount() << endl;
64          cout << "temp=" << temp << endl;
65          cin.ignore(5);
66          cin >> temp;
67          cout << "temp=" << temp << endl;
68          cin.ignore(80,'\n');
69     
70          cout << "Enter one last time => ";
71     
72          // Read the first word from the input buffer
73          cin >> temp;
74          cout << "temp=" << temp << endl;
75     
76          // Read 7 more bytes into temp
77          cout << "cin.readsome(temp,7)=" << cin.readsome(temp,7) << endl;
78          cout << "temp=" << temp << endl;
79          cout << "cin.readsome(temp,10)=" <<cin.readsome(temp,10) << endl;
80          cout << "temp=" << temp << endl;
81          return 0;
82      }


******  Output (MS Visual C++ 2008) ******

Enter something => Have a nice day.
temp=Have a
temp= nice d
ch=a
y.
Enter something else => Have a very nice day.
temp=Ha
temp=e a ve
ch=

cin.peek()=-1
cin.rdstate()=2
ch=r
temp=Xry nice day.
Enter some more => Have a totally excellent day.
cin.gcount()=6
temp=Have ace day.
temp=lly
Enter one last time => That's enough now.
temp=That's
cin.readsome(temp,7)=7
temp= enoughe day.
cin.readsome(temp,10)=6
temp= now.
he day.

******  Output (GNU ver. 4.32b) ******

Enter something => Have a nice day.
temp=Have a
temp= nice d
ch=a
y.
Enter something else => Have a very nice day.
temp=Ha
temp=e a ve
ch=

cin.peek()=-1
cin.rdstate()=4
ch=r
temp=Xry nice day.
Enter some more => Have a totally excellent day.
cin.gcount()=6
temp=Have ace day.
temp=lly
Enter one last time => That's enough now.
temp=That's
cin.readsome(temp,7)=0
temp=That's
cin.readsome(temp,10)=0
temp=That's

What happened on line 41?

The problem really occurred on line 36, cin.getline(temp,7);. The default delimiter for this version of getline() is '\n' (or more precisely, widen('\n')).  The getline() function expects to read the delimiter. If the delimiter is not encounter in the "n-1" characters, the the failbit is set, That is, the read in not successful, even though the n-1 characters were read and stored in the buffer. Advice, be careful with this function and check the stream state if there is any possibility that the delimiter may not be present.

Example 8-4 - ostream member functions: put() and write()
The following examples illustrates the use of ostream put() and write() functions.

1      // File: ex8-4.cpp - ostream member functions: put() and write()
2     
3      #include <iostream>
4      using namespace std;
5     
6      struct stuff {
7            int a;
8            short b;
9            long c;
10            float d;
11            double e;
12            char f;
13            char* g;
14            char h[16];
15      };
16     
17     
18      int main(void)
19      {
20          char text[] = "The quick brown fox jumped over the lazy poodle";
21          for (int i = 0; i< 20; i++) {
22              cout.put(text[i]);
23          }
24          cout.put('\n');
25     
26          cout.write(text,sizeof(text));
27          cout << endl;
28     
29          stuff thing;
30          thing.a = 57;
31          thing.b = 98;
32          thing.c = 123456789;
33          thing.d = 1.2;
34          thing.e = 2.7;
35          thing.f = '*';
36          thing.g = text;
37          strcpy(thing.h,"bet the farm");
38     
39          cout.write((char*)&thing,sizeof(thing));
40          cout << endl;
41     
42          return 0;
43      }


******  Output  ******

The quick brown fox
The quick brown fox jumped over the lazy poodle
9   b   §═[ÜÖÖ?ÜÖÖÖÖÖ♣@*♫☺ ╪5♀ bet the farm ↨

Input/Output Manipulators

Manipulators are functions or function-like operators that change the state of the I/O stream. Those manipulators with arguments require the <iomanip> header file.


Example 8-5 – Input/Output manipulators

The following examples illustrates the use of standard input/output manipulators.

1      // File: ex8-5.cpp - I/O Manipulators 2    
3      #include <iomanip>
4      using namespace std;
5    
6      #include "fmtflags.h"
7    
8      int main() {
9          // save the initial cout flags settings
10    
11          ios_base::fmtflags cout_fmtflags = cout.flags();
12    
13          // Display the cout flags
14          show_fmtflags(cout);
15    
16          // hex, oct, & dec manipulators
17          cout << hex << 123 << ' ' << oct << 123 << ' ' <<dec<<123<<endl;
18          show_fmtflags(cout);
19    
20          // Turn on showpos, uppercase, showpoint, left, hex, (dec on)
21          cout << setiosflags(ios::showpos|ios::uppercase|ios::showpoint|
22                              ios::showbase|ios::left|ios::hex)
23               << 123 << endl;
24          show_fmtflags(cout);
25    
26          // Clear the dec flag
27          cout << resetiosflags (ios::dec) << 123 << endl;
28          show_fmtflags(cout);
29    
30          // Demonstrate the setfill and setw manipulators
31          cout << setfill('$') << setw(10) << 123 << endl;
32          cout << 123 << endl;
33    
34          // Reset cout's flags back to the original settings
35          cout.flags(cout_fmtflags);
36    
37          // Turn on hex
38          cout << hex << 123 << endl;
39          show_fmtflags(cout);
40    
41          // Turn on octal
42          cout << oct << 123 << endl;
43          show_fmtflags(cout);
44    
45          // Demonstrate setprecision
46          cout << setprecision(3)
47            << 1.2 << ' '<< 3.14 << ' ' << 35 << ' ‘ << 3.14159 << endl;
48    
49          // Demonstrate setprecision with showpoint
50          cout << showpoint
51            << 1.2 << ' '<< 3.14 << ' ' << 35 << ' ‘ << 3.14159 << endl;
52    
53          // Demonstrate showpos
54          cout << showpos
55            << 1.2 << ' '<< 3.14 << ' ' << 35 << ' ‘ << 3.14159 << endl;
56    
57          show_fmtflags(cout);
58    
59          // Back to decimal
60          cout << dec
61            << 1.2 << ' '<< 3.14 << ' ' << 35 << ' ‘ << 3.14159 << endl;
62          show_fmtflags(cout);
63    
64          // What is truth?
65          cout << true << ' ' << boolalpha << true << endl;
66          show_fmtflags(cout);
67    
68          return 0;
69      }


******  Output  ******

cout ios_base::fmtflags set: dec skipws
7b 173 123
cout ios_base::fmtflags set: dec skipws
123
cout ios_base::fmtflags set: dec hex left showbase showpoint showpos skipws uppercase
0X7B
cout ios_base::fmtflags set: hex left showbase showpoint showpos skipws uppercase
0X7B$$$$$$
0X7B
7b
cout ios_base::fmtflags set: hex skipws
173
cout ios_base::fmtflags set: oct skipws
1.2 3.14 43 3.14
1.20 3.14 43 3.14
+1.20 +3.14 43 +3.14
cout ios_base::fmtflags set: oct showpoint showpos skipws
+1.20 +3.14 +35 +3.14
cout ios_base::fmtflags set: dec showpoint showpos skipws
1 true
cout ios_base::fmtflags set: boolalpha dec showpoint showpos skipws

Overloading the Insertion and Extraction Operators

Example 8-6 - Overloading the insertion operator

1      // File: ex8-6.cpp – Overloading the insertion operator
2     
3      #include <iostream>
4      using namespace std;
5     
6      const char* suit_name[4] = {"clubs","diamonds","hearts","spades"};
7      const char* value_name[13] = {"two","three","four","five","six",
8       "seven","eight","nine","ten","jack","queen","king","ace"};
9     
10      class card {
11        private:
12          int suit;
13          int value;
14        public:
15          card(int=0);
16        friend ostream& operator<< (ostream&,const card&);
17      };
18     
19      card::card(int x) {
20        suit = x / 13;
21        value = x % 13;
22      }
23     
24     
25      ostream& operator<<(ostream& s,const card& c) {
26        s << value_name[c.value] << " of " << suit_name[c.suit] << endl;
27        return s;
28      }
29     
30      int main(void)
31      {
32        card c1(47);
33        card c2;
34        cout << c1;
35        cout << c2;
36        cout << card(3) << card(4);
37     
38        return 0;
39      }


******  Output  ******

ten of spades
two of clubs
five of clubs
six of clubs

Example 8-7 - Overloading Insertion and Extraction

1      // File: ex8-7.cpp
2     
3      #include <iostream>
4      #include <cmath>
5      using namespace std;
6     
7      class fraction
8      {
9        private:
10          int numer;
11          int denom;
12        public:
13          fraction() {}
14          fraction(int n, int d) : numer(n), denom(d) {}
15          int get_numer(void) const { return numer; }
16          int get_denom(void) const { return denom; }
17          void reduce(void);
18        friend istream& operator>>(istream& s, fraction& f);
19      };
20     
21      void fraction::reduce(void)
22      {
23        int min;
24      // find the minimum of the denom and numer
25        min = abs(denom) < abs(numer) ? abs(denom) : abs(numer);
26        for (int i = 2; i <= min; i++)
27        {
28          while ((abs(numer) % i == 0) && (abs(denom) % i == 0))
29          {
30            numer /= i;
31            denom /= i;
32          }
33        }
34        return;
35      }
36     
37      // extraction's a friend
38      istream& operator>>(istream& s, fraction& f)
39      {
40        s >> f.numer >> f.denom;
41        return s;
42      }
43     
44      // insertion's not a friend
45      ostream& operator<<(ostream& s, fraction f)
46      {
47        f.reduce();
48        s << f.get_numer() << '/' << f.get_denom();
49        return s;
50      }
51      int main(void)
52      {
53        fraction f(3,4);
54        cout << f << endl;
55        fraction g(2,4);
56        cout << g << endl;
57        cout << "Enter a fraction: numerator denominator => ";
58        fraction h;
59        cin >> h;
60        cout << h << endl;
61        return 0;
62      }


******  Sample Run  ******

3/4
1/2
Enter a fraction: numerator denominator => 6 8
3/4

Why the the fraction passed by value in the overloaded insertion operator function?

Example 8-8 - Printing a deck

Here’s one more example of overloading the insertion operator.

1      // File: ex8-8.cpp – overloading the insertion operator
2     
3      #include <iostream>
4      #include <cmath>
5      using namespace std;
6     
7      const char suit_char[5] = "CDHS";
8      const char value_char[14] = "23456789TJQKA";
9     
10      class deck;                    // forward declare the deck
11     
12      class card
13      {
14        private:
15          int suit;
16          int value;
17        public:
18          card(int);
19        friend ostream& operator<<(ostream&,const deck&);
20      };
21     
22      card::card(int x)
23      {
24        suit = x / 13;
25        value = x % 13;
26      }
27     
28     
29      class deck
30      {
31        private:
32          card* d[52];
33        public:
34          deck();
35          ~deck();
36        friend ostream& operator<<(ostream&,const deck&);
37      };
38     
39      deck::deck()
40      {
41        for (int i = 0; i < 52; i++) d[i] = new card(i);
42      }
43     
44      deck::~deck()
45      {
46        for (int i = 0; i < 52; i++) delete d[i];
47      }
48      int main(void)
49      {
50        deck cards;
51        cout << cards;
52        return 0;
53      }
54     
55      ostream& operator<<(ostream& s,const deck& dk)
56      {
57        for (int i = 0; i < 52; i++)
58        {
59          s << value_char[dk.d[i]->value] << suit_char[dk.d[i]->suit];
60          if (i % 13 == 12) s << endl;
61         else s << ' ';
62        }
63        return s;
64      }


******  Output  ******

2C 3C 4C 5C 6C 7C 8C 9C TC JC QC KC AC
2D 3D 4D 5D 6D 7D 8D 9D TD JD QD KD AD
2H 3H 4H 5H 6H 7H 8H 9H TH JH QH KH AH
2S 3S 4S 5S 6S 7S 8S 9S TS JS QS KS AS

Why does operator<< need to be a friend of both the card and the deck classes?

沒有留言:

張貼留言