|
|
|
|
||
Chapter 4
|
||||||||||||||||||||||||||||||||||||
| cin | An istream_withassign object linked to standard input |
| cout | An ostream_withassign object linked to standard output |
| cerr | An ostream_withassign object linked to standard error that supports unbuffered output |
| clog | An ostream_withassign object linked to standard error that supports buffered output |
To generate output, you apply the insertion operator (<<) to cout , as shown in the following example:
cout << "Hello\n" ; |
Figure 4-1 Inheritance Diagram for the iostream Package
Obtaining input is similar to generating output, except that you apply the extraction operator (>>) to cin , as shown in the following example:
int eye, jay ; cin >> eye >> jay ; |
If you include these fragments of code in a program, your system expects users to type in two integer values (for eye and jay ) from a terminal. The iostream package supplies predefined extraction and insertion operators for all built-in data types, including char* .
This package also supports file manipulation. To connect a specific file to your program, instantiate one of the following class types:
ifstream (for file input)
ofstream (for file output)
fstream (for both input and output)
To format within character arrays, the iostream package includes the following associated class types:
istrstream (for fetching characters from an array)
ostrstream (for storing characters into an array)
strstream (for both fetching and storing characters into an array)
On systems with IEEE floating-point arithmetic, certain values may be printed as symbols for Infinity (for example, INF ) or Not a Number (for example, NaN ). |
Deriving Your Own Class from ios
If you derive your own class from the ios class, or from one of its derived classes, the ios subobject must be initialized properly during instantiation. Specifically, you must ensure that the streambuf pointer within the ios subobject is valid.
To do this, you can specify the ios(streambuf *) constructor as a member initializer for your class constructor. Optionally, you can call the ios::init(streambuf *) member function.
The predefined stream objects, cerr , cin , clog , and cout are thread safe only for individual calls into the C++ Class Library. You must provide synchronization around sequences of calls. For more information on synchronizing access to predefined stream objects, see the section on Global Declarations in this chapter.
User-defined stream objects are not thread safe, so you must provide synchronization around individual calls as well as sequences of calls. For more information on synchronizing access to user-defined objects, see Chapter 6 and the section on Global Declarations in this chapter.
The ios member function sync_with_stdio() is not thread safe. If your application calls this function, it must make the call before any threads use cerr , cin , clog , or cout .
These declarations are used by the iostream package but they are not members of any class.
#include <iostream.hxx>#include <iostream.h>
typedef long streamoff typedef long streampos ios &dec(ios &s); ios &hex(ios &s); ios &oct(ios &s); ios &lock(ios &s); ios &unlock(ios &s); istream &ws(istream &i); ostream &endl(ostream &o); ostream &ends(ostream &o); ostream &flush(ostream &o);
typedef long streamoff
Is the type representing a character offset into a stream. For more information, see the description of the seekoff and seekpos functions in the streambuf class.typedef long streampos
Is the type representing a character position in a stream. For more information, see the description of the seekoff and seekpos functions in the streambuf class.
The following functions insert values into a stream, extract values from a stream, or specify the conversion base format. For more information on the conversion base format flags, see the ios class.ios &dec(ios &s)
Sets the conversion base format for s to decimal, essentially clearing the ios::oct and ios::hex flags and setting the ios::dec flag.ios &hex(ios &s)
Sets the conversion base format for s to hexadecimal, essentially clearing the ios::oct and ios::dec flags and setting the ios::hex flag.ios &oct(ios &s)
Sets the conversion base format for s to octal, essentially clearing the ios::dec and ios::hex flags and setting the ios::oct flag.istream &ws(istream &i)
Extracts (skips) white-space characters from i.ostream &endl(ostream &o)
Ends a line by inserting a new-line character into o and flushing o.ostream &ends(ostream &o)
Ends a string by inserting a null '/0' character into o.ostream &flush(ostream &o)
Flushes o.
The following unparameterized manipulators are for use in synchronizing access to the predefined stream objects, cerr , cin , clog , and cout :ios &lock(ios &s)
Locks s if s is one of the predefined stream objects.ios &unlock(ios &s)
Unlocks s if s is one of the predefined stream objects.If your application needs to lock two or more of these objects at the same time, your application must adhere to the following locking order:
- cin
- cerr
- clog
- cout
For example, if your application needs to lock both cerr and cout , lock cerr first and cout second. The unlocking order is not important.
Keep in mind that when your application calls a member function for a predefined stream object, the member function will typically lock the object for the duration of the call. Therefore, if your application has locked one of the stream objects and then uses another, this use must also adhere to the predefined locking order. For example, your application should not send output to cerr while cout is locked.
The locking order necessarily matches the default ties between the stream objects as follows:
cin is tied to cout
cerr is tied to cout
clog is tied to cout
cout has no tiesAny input/output operation on a stream object causes the iostream package to flush the object to which it is tied. Thus, an output to cerr flushes cout .
| #1 |
|---|
#include <iostream.hxx>
#include <iomanip.hxx>
int main ()
{
int value = 10;
cout << hex << value << ','; // Change the base conversion format to
// hexadecimal; note that the default is
// decimal as set by the ios constructors.
cout << value << ','; // The base conversion format set in the
// previous line is still active.
cout << dec << value << endl; // Change the base conversion format to
// decimal; lastly, insert a new-line
// character into the stream and flush
// cout.
return 0;
}
|
The output is a,a,10.
| #2 |
|---|
#include <string.hxx>
#include <iostream.hxx>
void print_name(String &name)
{
cout << lock << "Hello, " << name << endl << unlock;
}
|
This synchronizes access to the cout object so that the "Hello, " , name, and new-line character are written to cout as a single unit. If you do not use the lock and unlock manipulators in this example, another thread could possibly insert its own text into cout in the midst of your output.
#include <iomanip.hxx>#include <iomanip.h>
SMANIP(long) resetiosflags(long); SMANIP(long) setiosflags(long); SMANIP(int) setfill(int); SMANIP(int) setprecision(int); SMANIP(int) setw(int w); SMANIPREF(Mutex) lock(Mutex &m) SMANIPREF(Mutex) unlock(Mutex &m)
These functions are used for extending the iostream package with user-defined parameterized manipulators.SMANIP(long) resetiosflags(long x)
In the stream ( ios or a stream derived from ios ), clears the format flags denoted by x.SMANIP(int) setfill(int x)
Sets the fill character to be the value specified by x. The fill character is a data member of the ios class; however, setting it with this function affects only output streams.SMANIP(long) setiosflags(long x)
In the stream ( ios or a stream derived from ios ), turns on the format flags denoted by x. If you are setting a flag that is part of a collection (for example, basefield ), note that this manipulator does not clear the other flags in the collection.SMANIP(int) setprecision(int x)
Sets the variable that controls the number of digits inserted by the floating-point inserter to be x. This variable is a data member of the ios class; however, setting it with this function affects only output streams.SMANIP(int) setw(int w)
In the stream ( ios or a stream derived from ios ), sets the field width of the stream to w.
The following parameterized manipulators are for use in synchronizing access to user-defined stream objects. To use these manipulators, you must first define a Mutex object, which you then pass to the manipulator. The association of a Mutex object with a stream object is not enforced by the iostream package. This association is enforced only by you, the programmer. Refer to Chapter 6 for information on the Mutex class.SMANIPREF(Mutex) lock(Mutex &m)
Locks the recursive Mutex represented by m.SMANIPREF(Mutex) unlock(Mutex &m)
Unlocks the recursive Mutex represented by m.
| #1 |
|---|
char c;
cin >> resetiosflags(ios::skipws)
>> c
>> setiosflags(ios::skipws);
|
Turns off the flag (resets it to 0) that tells the extractor (>>) to skip leading white space and then turns that flag back on again (sets it to 1).
| #2 |
|---|
cout.fill(*)
cout.setf(ios::left,ios::adjustfield);
cout << setw(6) << 23 << "," ;
cout.fill(%);
cout.setf(ios::right,ios::adjustfield);
cout << setw(4) << 34 << "\n" ;
|
Places padding characters (specified by the fill state variable) after the first number and before the second number. The output is 23****,%%34 .
| #3 |
|---|
#include <string.hxx>
#include <fstream.hxx>
#include <mutex.hxx>
#include <iomanip.hxx>
main ()
{
String name("Henry");
void print_name (String &, ostream &, Mutex &);
ofstream mystream(1);
Mutex mystream_lock;
print_name(name, mystream, mystream_lock);
return 0;
}
void print_name(String &name, ostream &stream, Mutex &stream_lock)
{
stream << lock(stream_lock) << "Hello, " << name << endl
<< unlock(stream_lock);
}
|
This example associates a Mutex object with a stream object to synchronize access to the stream. The Mutex is locked before using the stream and then unlocked afterwards. For the synchronization to work properly, each thread that uses this stream must perform the same lock/unlock sequence with the same Mutex.
IMANIP(TYPE) class
IOMANIP(TYPE) class
OMANIP(TYPE) class
SMANIP(TYPE) class
Provides a data buffer abstraction for input/output facilities through file descriptors.
#include <fstream.hxx>#include <fstream.h>
class filebuf: public streambuf { public: static const int openprot; filebuf(); filebuf(int fd); filebuf(int fd, char *p, int len); ~filebuf(); filebuf *attach(int fd); filebuf *close(); int fd(); int is_open(); filebuf *open(const char *name, int mode, int prot = openprot); virtual int overflow(int = EOF); virtual streampos seekoff(streamoff, seek_dir, int mode); virtual streampos seekpos(streampos, int mode); virtual streambuf *setbuf(char *p, int len); virtual int sync(); virtual int underflow(); };
This class specializes the streambuf class to use a file as a repository of characters. Writing to the file consumes characters; reading from the file produces characters. Files that allow searches are said to be seekable. When a file is readable and writable, the filebuf object permits character insertion and extraction.If your program expects a buffer to be allocated when none was allocated, then the iostream package allocates a default buffer with a length specified by BUFSIZ as defined in stdio.h . The package then issues the following warning:
Warning; a null pointer to streambuf was passed to ios::init()
const int openprot = 0644
Provides default protection for the open() function. (For an explanation of the file protection, see the chmod(1) reference page.)
filebuf()
Constructs a filebuf object that is initially closed.filebuf(int fd)
Constructs a filebuf object connected to file descriptor fd.filebuf(int fd, char *p, int len)
Constructs a filebuf object connected to file descriptor fd, which is initialized to use the reserve area (buffer) starting at p and containing len bytes.~filebuf()
Deletes a filebuf object.
filebuf *attach(int fd)
Connects the filebuf object to an open file whose descriptor is passed through the fd argument. It normally returns a reference to the filebuf object, but returns 0 if the filebuf object is connected to an open file.filebuf *close()
Flushes any waiting output, closes the file descriptor, and disconnects a filebuf object. Unless an error occurs, the filebuf object's error state will be cleared. The close() function returns the address of the filebuf object unless errors occur, in which case this function returns 0. Even if errors occur, close() leaves the file descriptor and filebuf object closed.int fd()
Returns the file descriptor associated with a filebuf object. If the filebuf object is closed, fd returns EOF .int is_open()
Returns a nonzero value when a filebuf object is connected to a file descriptor; otherwise, it returns 0.filebuf *open(const char *name, int mode, int prot)
Opens a file with the name specified by name and connects a filebuf object to it. If the file does not exist, the function tries to create it with the protection mode prot unless ios::nocreate is specified in mode. By default, prot is filebuf::openprot .The function fails if the filebuf object is open. The open() function normally returns the address of the filebuf object, but returns 0 if an error occurs. The members of open_mode are bits that may be joined together by or (because this joining takes an int , open() takes an int rather than an open_mode argument). For an explanation of the meanings of these bits in open_mode , see the Enumerated Types section for the ios class.
virtual int overflow(int c)
Called to consume characters in classes derived from streambuf . If c is not EOF , this function must also either save c or consume it. Although it can be called at other times, this function usually is called when the put area is full and an attempt is being made to store a new character. The normal action is to consume the characters between pbase() and pptr() , call setp() to establish a new put area, and (if c != EOF ) store c using sputc() . A call to overflow(c) should return EOF to indicate an error; otherwise, it should return something else.virtual streampos seekoff(streamoff off, seek_dir dir, int mode)
Moves the get pointer, put pointer, or both as designated by the off and dir arguments. It may fail if the file does not support seeking, or if the attempted motion is otherwise invalid (for example, attempting to seek a position before the beginning of the file). The off argument is interpreted as a count relative to the place in the file specified by dir. The mode argument is ignored. A call to seekoff() returns the new position or EOF if a failure occurs. After a failure, the position of the file is undefined.virtual streampos seekpos(streampos pos, int mode)
Moves the file to a position pos. The mode argument is ignored. The function normally returns pos but it returns EOF on failure.virtual streambuf *setbuf(char *p, int len)
Sets up the reserve area as the number of bytes specified in the second argument, beginning at the pointer specified in the first argument. If the pointer is null, or the number of bytes is less than 1, the filebuf object is unbuffered. This function normally returns a pointer to the filebuf object; however, if the filebuf object is open and a buffer is allocated, then no changes are made to the reserve area and to the buffering status, and setbuf() returns 0.virtual int sync()
Tries to get the state of the get pointer, the put pointer, or both, to agree (synchronize) with the state of the file to which the filebuf object is connected. This means that the function may write characters to the file if some of the characters have been buffered for output, or the function may try to reposition (seek) the file if characters have been read and buffered for input. Normally sync() returns 0, but it returns EOF if synchronization is not possible.When certain characters must be written together, the program should use setbuf() (or a constructor) to ensure that the reserve area is at least as large as the number of characters to be written together. Your program can then call sync() , store the characters, and then call sync() once again.
virtual int underflow()
Called in classes derived from streambuf to supply characters for fetching; that is, to create a condition in which the get area is not empty. If the function is called when characters occupy the get area, it should create a nonempty area and return the next character (which it should also leave in the get area). If no more characters are available, underflow() should return EOF and leave an empty get area.
ios class
streambuf class
| Previous | Next | Contents | Index |
| privacy statement and legal notices |