| \input texinfo @c -*-Texinfo-*- |
| @c Copyright (c) 1993 Free Software Foundation, Inc. |
| |
| @c %**start of header |
| @setfilename iostream.info |
| @settitle The GNU C++ Iostream Library |
| @setchapternewpage odd |
| @c %**end of header |
| |
| @ifinfo |
| @format |
| START-INFO-DIR-ENTRY |
| * iostream: (iostream). The C++ input/output facility. |
| END-INFO-DIR-ENTRY |
| @end format |
| |
| This file describes libio, the GNU library for C++ iostreams and C stdio. |
| |
| libio includes software developed by the University of California, |
| Berkeley. |
| |
| Copyright (C) 1993 Free Software Foundation, Inc. |
| |
| Permission is granted to make and distribute verbatim copies of |
| this manual provided the copyright notice and this permission notice |
| are preserved on all copies. |
| |
| @ignore |
| Permission is granted to process this file through TeX and print the |
| results, provided the printed document carries copying permission |
| notice identical to this one except for the removal of this paragraph |
| (this paragraph not being relevant to the printed manual). |
| |
| @end ignore |
| Permission is granted to copy and distribute modified versions of this |
| manual under the conditions for verbatim copying, provided also that the |
| entire resulting derived work is distributed under the terms of a |
| permission notice identical to this one. |
| |
| Permission is granted to copy and distribute translations of this manual |
| into another language, under the above conditions for modified versions. |
| @end ifinfo |
| |
| @finalout |
| @syncodeindex fn cp |
| @syncodeindex vr cp |
| |
| @titlepage |
| @title The GNU C++ Iostream Library |
| @subtitle Reference Manual for @code{libio} Version 0.64 |
| @sp 3 |
| @author Per Bothner @hfill @code{bothner@@cygnus.com} |
| @author Cygnus Support @hfill @code{doc@@cygnus.com} |
| @page |
| |
| @vskip 0pt plus 1filll |
| Copyright @copyright{} 1993 Free Software Foundation, Inc. |
| |
| @code{libio} includes software developed by the University of |
| California, Berkeley. |
| |
| @code{libio} uses floating-point software written by David M. Gay, which |
| includes the following notice: |
| |
| @quotation |
| The author of this software is David M. Gay. |
| |
| Copyright (c) 1991 by AT&T. |
| |
| Permission to use, copy, modify, and distribute this software for any |
| purpose without fee is hereby granted, provided that this entire notice |
| is included in all copies of any software which is or includes a copy |
| or modification of this software and in all copies of the supporting |
| documentation for such software. |
| |
| THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED |
| WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY |
| REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY |
| OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. |
| @end quotation |
| |
| Permission is granted to make and distribute verbatim copies of |
| this manual provided the copyright notice and this permission notice |
| are preserved on all copies. |
| |
| Permission is granted to copy and distribute modified versions of this |
| manual under the conditions for verbatim copying, provided also that the |
| entire resulting derived work is distributed under the terms of a |
| permission notice identical to this one. |
| |
| Permission is granted to copy and distribute translations of this manual |
| into another language, under the above conditions for modified versions. |
| @end titlepage |
| |
| @ifinfo |
| @node Top |
| @top The GNU C++ Iostream Library |
| |
| This file provides reference information on the GNU C++ iostream library |
| (@code{libio}), version 0.64. |
| |
| @menu |
| * Introduction:: |
| * Operators:: Operators and default streams. |
| * Streams:: Stream classes. |
| * Files and Strings:: Classes for files and strings. |
| * Streambuf:: Using the streambuf layer. |
| * Stdio:: C input and output. |
| * Index:: |
| @end menu |
| @end ifinfo |
| |
| @node Introduction |
| @chapter Introduction |
| |
| The iostream classes implement most of the features of AT&T version 2.0 |
| iostream library classes, and most of the features of the ANSI X3J16 |
| library draft (which is based on the AT&T design). |
| |
| This manual is meant as a reference; for tutorial material on iostreams, |
| see the corresponding section of any recent popular introduction to C++. |
| |
| @menu |
| * Copying:: Special GNU licensing terms for libio. |
| * Acknowledgements:: Contributors to GNU iostream. |
| @end menu |
| |
| @node Copying |
| @section Licensing terms for @code{libio} |
| |
| Since the @code{iostream} classes are so fundamental to standard C++, |
| the Free Software Foundation has agreed to a special exception to its |
| standard license, when you link programs with @code{libio.a}: |
| |
| @quotation |
| As a special exception, if you link this library with files |
| compiled with a GNU compiler to produce an executable, this does not cause |
| the resulting executable to be covered by the GNU General Public License. |
| This exception does not however invalidate any other reasons why |
| the executable file might be covered by the GNU General Public License. |
| @end quotation |
| |
| The code is under the @sc{gnu} General Public License (version 2) for |
| all other purposes than linking with this library; that means that you |
| can modify and redistribute the code as usual, but remember that if you |
| do, your modifications, and anything you link with the modified code, |
| must be available to others on the same terms. |
| |
| These functions are also available as part of the @code{libg++} |
| library; if you link with that library instead of @code{libio}, the |
| @sc{gnu} Library General Public License applies. |
| |
| @node Acknowledgements |
| @section Acknowledgements |
| |
| Per Bothner wrote most of the @code{iostream} library, but some portions |
| have their origins elsewhere in the free software community. Heinz |
| Seidl wrote the IO manipulators. The floating-point conversion software |
| is by David M. Gay of AT&T. Some code was derived from parts of BSD |
| 4.4, which was written at the University of California, Berkeley. |
| |
| The iostream classes are found in the @code{libio} library. An early |
| version was originally distributed in @code{libg++}, and they are still |
| included there as well, for convenience if you need other @code{libg++} |
| classes. Doug Lea was the original author of @code{libg++}, and some of |
| the file-management code still in @code{libio} is his. |
| |
| Various people found bugs or offered suggestions. Hongjiu Lu worked |
| hard to use the library as the default stdio implementation for Linux, |
| and has provided much stress-testing of the library. |
| |
| @node Operators |
| @chapter Operators and Default Streams |
| |
| The @sc{gnu} iostream library, @file{libio}, implements the standard |
| input and output facilities for C++. These facilities are roughly |
| analogous (in their purpose and ubiquity, at least) with those defined |
| by the C @file{stdio} functions. |
| |
| Although these definitions come from a library, rather than being part |
| of the ``core language'', they are sufficiently central to be specified |
| in the latest working papers for C++. |
| |
| You can use two operators defined in this library for basic input and |
| output operations. They are familiar from any C++ introductory |
| textbook: @code{<<} for output, and @code{>>} for input. (Think of data |
| flowing in the direction of the ``arrows''.) |
| |
| These operators are often used in conjunction with three streams that |
| are open by default: |
| |
| @deftypevar ostream cout |
| The standard output stream, analogous to the C @code{stdout}. |
| @end deftypevar |
| |
| @deftypevar istream cin |
| The standard input stream, analogous to the C @code{stdin}. |
| @end deftypevar |
| |
| @deftypevar ostream cerr |
| An alternative output stream for errors, analogous to the C |
| @code{stderr}. |
| @end deftypevar |
| |
| @noindent |
| For example, this bare-bones C++ version of the traditional ``hello'' |
| program uses @code{<<} and @code{cout}: |
| |
| @example |
| #include <iostream.h> |
| |
| int main(int argc, char **argv) |
| @{ |
| cout << "Well, hi there.\n"; |
| return 0; |
| @} |
| @end example |
| |
| Casual use of these operators may be seductive, but---other than in |
| writing throwaway code for your own use---it is not necessarily simpler |
| than managing input and output in any other language. For example, |
| robust code should check the state of the input and output streams |
| between operations (for example, using the method @code{good}). |
| @xref{States,,Checking the state of a stream}. You may also need to |
| adjust maximum input or output field widths, using manipulators like |
| @code{setw} or @code{setprecision}. |
| |
| @defop Operator ostream << |
| Write output to an open output stream of class @code{ostream}. |
| Defined by this library on any @var{object} of a C++ primitive type, and |
| on other classes of the library. You can overload the definition for any |
| of your own applications' classes. |
| |
| Returns a reference to the implied argument @code{*this} (the open stream it |
| writes on), permitting statements like |
| @example |
| cout << "The value of i is " << i << "\n"; |
| @end example |
| @end defop |
| |
| @defop Operator istream >> |
| Read input from an open input stream of class @code{istream}. Defined |
| by this library on primitive numeric, pointer, and string types; you can |
| extend the definition for any of your own applications' classes. |
| |
| Returns a reference to the implied argument @code{*this} (the open stream |
| it reads), permitting multiple inputs in one statement. |
| @end defop |
| |
| @node Streams |
| @chapter Stream Classes |
| |
| The previous chapter referred in passing to the classes @code{ostream} |
| and @code{istream}, for output and input respectively. These classes |
| share certain properties, captured in their base class @code{ios}. |
| |
| @menu |
| * Ios:: Shared properties. |
| * Ostream:: Managing output streams. |
| * Istream:: Managing input streams. |
| * Iostream:: Input and output together. |
| @end menu |
| |
| @node Ios |
| @section Shared properties: class @code{ios} |
| |
| The base class @code{ios} provides methods to test and manage the state |
| of input or output streams. |
| |
| @code{ios} delegates the job of actually reading and writing bytes to |
| the abstract class @code{streambuf}, which is designed to provide |
| buffered streams (compatible with C, in the @sc{gnu} implementation). |
| @xref{Streambuf,,Using the @code{streambuf} layer}, for information on |
| the facilities available at the @code{streambuf} level. |
| |
| @deftypefn Constructor {} ios::ios ([streambuf* @var{sb} @w{[, ostream*} @var{tie}]) |
| The @code{ios} constructor by default initializes a new @code{ios}, and |
| if you supply a @code{streambuf} @var{sb} to associate with it, sets the |
| state @code{good} in the new @code{ios} object. It also sets the |
| default properties of the new object. |
| |
| @ignore |
| @c FIXME--future: this (a) doesn't work, (b) is controversial at ANSI |
| An @code{ios} without a @code{streambuf} has the state @code{bad} until |
| you supply a @code{streambuf}; you can do that by assigning a new value |
| to the @code{ios} with @samp{=}. |
| @end ignore |
| |
| You can also supply an optional second argument @var{tie} to the |
| constructor: if present, it is an initial value for @code{ios::tie}, to |
| associate the new @code{ios} object with another stream. |
| @end deftypefn |
| |
| @deftypefn Destructor {} ios::~ios () |
| The @code{ios} destructor is virtual, permitting application-specific |
| behavior when a stream is closed---typically, the destructor frees any |
| storage associated with the stream and releases any other associated |
| objects. |
| @end deftypefn |
| |
| @c FIXME-future: Is @deftypefn really the best way of displaying these? |
| |
| @c FIXME-future: Undocumented: ios::_throw_failure, ios::exceptions; things |
| @c controlled by _STREAM_COMPAT; ios::Init; ios::_IO_fix_vtable. |
| |
| @menu |
| * States:: Checking the state of a stream. |
| * Format Control:: Choices in formatting. |
| * Manipulators:: Convenient ways of changing stream properties. |
| * Extending:: Extended data fields. |
| * Synchronization:: Synchronizing related streams. |
| * Streambuf from Ios:: Reaching the underlying streambuf. |
| @end menu |
| |
| @node States |
| @subsection Checking the state of a stream |
| |
| Use this collection of methods to test for (or signal) errors and other |
| exceptional conditions of streams: |
| |
| @deftypefn Method {ios::operator void*} () const |
| You can do a quick check on the state of the most recent operation on a |
| stream by examining a pointer to the stream itself. The pointer is |
| arbitrary except for its truth value; it is true if no failures have |
| occurred (@code{ios::fail} is not true). For example, you might ask for |
| input on @code{cin} only if all prior output operations succeeded: |
| |
| @example |
| if (cout) |
| @{ |
| // Everything OK so far |
| cin >> new_value; |
| @dots{} |
| @} |
| @end example |
| @end deftypefn |
| |
| @deftypefn Method {ios::operator !} () const |
| In case it is more convenient to check whether something has failed, the |
| operator @code{!} returns true if @code{ios::fail} is true (an operation |
| has failed). For example, |
| you might issue an error message if input failed: |
| |
| @example |
| if (!cin) |
| @{ |
| // Oops |
| cerr << "Eh?\n"; |
| @} |
| @end example |
| @end deftypefn |
| |
| @deftypefn Method iostate ios::rdstate () const |
| Return the state flags for this stream. The value is from the |
| enumeration @code{iostate}. You can test for any combination of |
| |
| @vtable @code |
| @item goodbit |
| There are no indications of exceptional states on this stream. |
| |
| @item eofbit |
| End of file. |
| |
| @item failbit |
| An operation has failed on this stream; this usually indicates bad |
| format of input. |
| |
| @item badbit |
| The stream is unusable. |
| @end vtable |
| @end deftypefn |
| |
| @deftypefn Method void ios::setstate (iostate @var{state}) |
| @findex ios::set |
| Set the state flag for this stream to @var{state} @emph{in addition to} |
| any state flags already set. Synonym (for upward compatibility): |
| @code{ios::set}. |
| |
| See @code{ios::clear} to set the stream state without regard to existing |
| state flags. See @code{ios::good}, @code{ios::eof}, @code{ios::fail}, |
| and @code{ios::bad}, to test the state. |
| @end deftypefn |
| |
| @deftypefn Method int ios::good () const |
| Test the state flags associated with this stream; true if no error |
| indicators are set. |
| @end deftypefn |
| |
| @deftypefn Method int ios::bad () const |
| Test whether a stream is marked as unusable. (Whether |
| @code{ios::badbit} is set.) |
| @end deftypefn |
| |
| @deftypefn Method int ios::eof () const |
| True if end of file was reached on this stream. (If @code{ios::eofbit} |
| is set.) |
| @end deftypefn |
| |
| @deftypefn Method int ios::fail () const |
| Test for any kind of failure on this stream: @emph{either} some |
| operation failed, @emph{or} the stream is marked as bad. (If either |
| @code{ios::failbit} or @code{ios::badbit} is set.) |
| @end deftypefn |
| |
| @deftypefn Method void ios::clear (iostate @var{state}) |
| @c FIXME-future: There is some complication to do with buffering and _throw_failure |
| Set the state indication for this stream to the argument @var{state}. |
| You may call @code{ios::clear} with no argument, in which case the state |
| is set to @code{good} (no errors pending). |
| |
| See @code{ios::good}, @code{ios::eof}, @code{ios::fail}, and |
| @code{ios::bad}, to test the state; see @code{ios::set} or |
| @code{ios::setstate} for an alternative way of setting the state. |
| @end deftypefn |
| |
| @node Format Control |
| @subsection Choices in formatting |
| |
| These methods control (or report on) settings for some details of |
| controlling streams, primarily to do with formatting output: |
| |
| @deftypefn Method char ios::fill () const |
| Report on the padding character in use. |
| @end deftypefn |
| |
| @deftypefn Method char ios::fill (char @var{padding}) |
| Set the padding character. You can also use the manipulator |
| @code{setfill}. @xref{Manipulators,,Changing stream properties in |
| expressions}. |
| |
| Default: blank. |
| @end deftypefn |
| |
| @deftypefn Method int ios::precision () const |
| Report the number of significant digits currently in use for output of |
| floating point numbers. |
| |
| Default: @code{6}. |
| @end deftypefn |
| |
| @deftypefn Method int ios::precision (int @var{signif}) |
| Set the number of significant digits (for input and output numeric |
| conversions) to @var{signif}. |
| |
| @findex setprecision |
| @cindex setting @code{ios::precision} |
| You can also use the manipulator @code{setprecision} for this purpose. |
| @xref{Manipulators,,Changing stream properties using manipulators}. |
| @end deftypefn |
| |
| @deftypefn Method int ios::width () const |
| Report the current output field width setting (the number of |
| characters to write on the next @samp{<<} output operation). |
| |
| Default: @code{0}, which means to use as many characters as necessary. |
| @end deftypefn |
| |
| @deftypefn Method int ios::width (int @var{num}) |
| Set the input field width setting to @var{num}. Return the |
| @emph{previous} value for this stream. |
| |
| @findex setw |
| @cindex setting @code{ios::width} |
| This value resets to zero (the default) every time you use @samp{<<}; it is |
| essentially an additional implicit argument to that operator. You can |
| also use the manipulator @code{setw} for this purpose. |
| @xref{Manipulators,,Changing stream properties using manipulators}. |
| @end deftypefn |
| |
| @need 2000 |
| @deftypefn Method fmtflags ios::flags () const |
| Return the current value of the complete collection of flags controlling |
| the format state. These are the flags and their meanings when set: |
| |
| @vtable @code |
| @item ios::dec |
| @itemx ios::oct |
| @itemx ios::hex |
| What numeric base to use in converting integers from internal to display |
| representation, or vice versa: decimal, octal, or hexadecimal, |
| respectively. (You can change the base using the manipulator |
| @code{setbase}, or any of the manipulators @code{dec}, @code{oct}, or |
| @code{hex}; @pxref{Manipulators,,Changing stream properties in |
| expressions}.) |
| |
| On input, if none of these flags is set, read numeric constants |
| according to the prefix: decimal if no prefix (or a @samp{.} suffix), |
| octal if a @samp{0} prefix is present, hexadecimal if a @samp{0x} prefix |
| is present. |
| |
| Default: @code{dec}. |
| |
| @item ios::fixed |
| Avoid scientific notation, and always show a fixed number of digits after |
| the decimal point, according to the output precision in effect. |
| Use @code{ios::precision} to set precision. |
| |
| @item ios::left |
| @itemx ios::right |
| @itemx ios::internal |
| Where output is to appear in a fixed-width field; left-justified, |
| right-justified, or with padding in the middle (e.g. between a numeric |
| sign and the associated value), respectively. |
| |
| @item ios::scientific |
| Use scientific (exponential) notation to display numbers. |
| |
| @item ios::showbase |
| Display the conventional prefix as a visual indicator of the conversion |
| base: no prefix for decimal, @samp{0} for octal, @samp{0x} for hexadecimal. |
| |
| @item ios::showpoint |
| Display a decimal point and trailing zeros after it to fill out numeric |
| fields, even when redundant. |
| |
| @item ios::showpos |
| Display a positive sign on display of positive numbers. |
| |
| @item ios::skipws |
| Skip white space. (On by default). |
| |
| @item ios::stdio |
| Flush the C @code{stdio} streams @code{stdout} and @code{stderr} after |
| each output operation (for programs that mix C and C++ output conventions). |
| |
| @item ios::unitbuf |
| Flush after each output operation. |
| |
| @item ios::uppercase |
| Use upper-case characters for the non-numeral elements in numeric |
| displays; for instance, @samp{0X7A} rather than @samp{0x7a}, or |
| @samp{3.14E+09} rather than @samp{3.14e+09}. |
| @end vtable |
| @end deftypefn |
| |
| @deftypefn Method fmtflags ios::flags (fmtflags @var{value}) |
| Set @var{value} as the complete collection of flags controlling the |
| format state. The flag values are described under @samp{ios::flags ()}. |
| |
| Use @code{ios::setf} or @code{ios::unsetf} to change one property at a |
| time. |
| @end deftypefn |
| |
| @deftypefn Method fmtflags ios::setf (fmtflags @var{flag}) |
| Set one particular flag (of those described for @samp{ios::flags ()}; |
| return the complete collection of flags @emph{previously} in effect. |
| (Use @code{ios::unsetf} to cancel.) |
| @end deftypefn |
| |
| @deftypefn Method fmtflags ios::setf (fmtflags @var{flag}, fmtflags @var{mask}) |
| Clear the flag values indicated by @var{mask}, then set any of them that |
| are also in @var{flag}. (Flag values are described for @samp{ios::flags |
| ()}.) Return the complete collection of flags @emph{previously} in |
| effect. (See @code{ios::unsetf} for another way of clearing flags.) |
| @end deftypefn |
| |
| @deftypefn Method fmtflags ios::unsetf (fmtflags @var{flag}) |
| Make certain @var{flag} (a combination of flag values described for |
| @samp{ios::flags ()}) is not set for this stream; converse of |
| @code{ios::setf}. Returns the old values of those flags. |
| @c FIXME-future: should probably be fixed to give same result as setf. |
| @end deftypefn |
| |
| @node Manipulators |
| @subsection Changing stream properties using manipulators |
| |
| For convenience, @var{manipulators} provide a way to change certain |
| properties of streams, or otherwise affect them, in the middle of |
| expressions involving @samp{<<} or @samp{>>}. For example, you might |
| write |
| |
| @example |
| cout << "|" << setfill('*') << setw(5) << 234 << "|"; |
| @end example |
| |
| @noindent |
| to produce @samp{|**234|} as output. |
| |
| @deftypefn Manipulator {} ws |
| Skip whitespace. |
| @end deftypefn |
| |
| @deftypefn Manipulator {} flush |
| Flush an output stream. For example, @samp{cout << @dots{} <<flush;} |
| has the same effect as @samp{cout << @dots{}; cout.flush();}. |
| @end deftypefn |
| |
| @deftypefn Manipulator {} endl |
| Write an end of line character @samp{\n}, then flushes the output stream. |
| @end deftypefn |
| |
| @deftypefn Manipulator {} ends |
| Write @samp{\0} (the string terminator character). |
| @end deftypefn |
| |
| @deftypefn Manipulator {} setprecision (int @var{signif}) |
| You can change the value of @code{ios::precision} in @samp{<<} |
| expressions with the manipulator @samp{setprecision(@var{signif})}; for |
| example, |
| |
| @example |
| cout << setprecision(2) << 4.567; |
| @end example |
| |
| @noindent |
| prints @samp{4.6}. Requires @file{#include <iomanip.h>}. |
| @end deftypefn |
| |
| @deftypefn Manipulator {} setw (int @var{n}) |
| You can change the value of @code{ios::width} in @samp{<<} expressions |
| with the manipulator @samp{setw(@var{n})}; for example, |
| |
| @example |
| cout << setw(5) << 234; |
| @end example |
| |
| @noindent |
| prints @w{@samp{ 234}} with two leading blanks. Requires @file{#include |
| <iomanip.h>}. |
| @end deftypefn |
| |
| @deftypefn Manipulator {} setbase (int @var{base}) |
| Where @var{base} is one of @code{10} (decimal), @code{8} (octal), or |
| @code{16} (hexadecimal), change the base value for numeric |
| representations. Requires @file{#include <iomanip.h>}. |
| @end deftypefn |
| |
| @deftypefn Manipulator {} dec |
| Select decimal base; equivalent to @samp{setbase(10)}. |
| @end deftypefn |
| |
| @deftypefn Manipulator {} hex |
| Select hexadecimal base; equivalent to @samp{setbase(16)}. |
| @end deftypefn |
| |
| @deftypefn Manipulator {} oct |
| Select octal base; equivalent to @samp{setbase(8)}. |
| @end deftypefn |
| |
| @deftypefn Manipulator {} setfill (char @var{padding}) |
| Set the padding character, in the same way as @code{ios::fill}. |
| Requires @file{#include <iomanip.h>}. |
| @end deftypefn |
| |
| @node Extending |
| @subsection Extended data fields |
| |
| A related collection of methods allows you to extend this collection of |
| flags and parameters for your own applications, without risk of conflict |
| between them: |
| |
| @deftypefn Method {static fmtflags} ios::bitalloc () |
| Reserve a bit (the single bit on in the result) to use as a flag. Using |
| @code{bitalloc} guards against conflict between two packages that use |
| @code{ios} objects for different purposes. |
| |
| This method is available for upward compatibility, but is not in the |
| @sc{ansi} working paper. The number of bits available is limited; a |
| return value of @code{0} means no bit is available. |
| @end deftypefn |
| |
| @deftypefn Method {static int} ios::xalloc () |
| Reserve space for a long integer or pointer parameter. The result is a |
| unique nonnegative integer. You can use it as an index to |
| @code{ios::iword} or @code{ios::pword}. Use @code{xalloc} to arrange |
| for arbitrary special-purpose data in your @code{ios} objects, without |
| risk of conflict between packages designed for different purposes. |
| @end deftypefn |
| |
| @deftypefn Method long& ios::iword (int @var{index}) |
| Return a reference to arbitrary data, of long integer type, stored in an |
| @code{ios} instance. @var{index}, conventionally returned from |
| @code{ios::xalloc}, identifies what particular data you need. |
| @end deftypefn |
| |
| @deftypefn Method long ios::iword (int @var{index}) const |
| Return the actual value of a long integer stored in an @code{ios}. |
| @end deftypefn |
| |
| @deftypefn Method void*& ios::pword (int @var{index}) |
| Return a reference to an arbitrary pointer, stored in an @code{ios} |
| instance. @var{index}, originally returned from @code{ios::xalloc}, |
| identifies what particular pointer you need. |
| @end deftypefn |
| |
| @deftypefn Method void* ios::pword (int @var{index}) const |
| Return the actual value of a pointer stored in an @code{ios}. |
| @end deftypefn |
| |
| @node Synchronization |
| @subsection Synchronizing related streams |
| |
| You can use these methods to synchronize related streams with |
| one another: |
| |
| @deftypefn Method ostream* ios::tie () const |
| Report on what output stream, if any, is to be flushed before accessing |
| this one. A pointer value of @code{0} means no stream is tied. |
| @end deftypefn |
| |
| @deftypefn Method ostream* ios::tie (ostream* @var{assoc}) |
| Declare that output stream @var{assoc} must be flushed before accessing |
| this stream. |
| @end deftypefn |
| |
| @deftypefn Method int ios::sync_with_stdio ([int @var{switch}]) |
| Unless iostreams and C @code{stdio} are designed to work together, you |
| may have to choose between efficient C++ streams output and output |
| compatible with C @code{stdio}. Use @samp{ios::sync_with_stdio()} to |
| select C compatibility. |
| |
| The argument @var{switch} is a @sc{gnu} extension; use @code{0} as the |
| argument to choose output that is not necessarily compatible with C |
| @code{stdio}. The default value for @var{switch} is @code{1}. |
| |
| If you install the @code{stdio} implementation that comes with @sc{gnu} |
| @code{libio}, there are compatible input/output facilities for both C |
| and C++. In that situation, this method is unnecessary---but you may |
| still want to write programs that call it, for portability. |
| @end deftypefn |
| |
| @node Streambuf from Ios |
| @subsection Reaching the underlying @code{streambuf} |
| |
| Finally, you can use this method to access the underlying object: |
| |
| @deftypefn Method streambuf* ios::rdbuf () const |
| Return a pointer to the @code{streambuf} object that underlies this |
| @code{ios}. |
| @end deftypefn |
| |
| @node Ostream |
| @section Managing output streams: class @code{ostream} |
| |
| Objects of class @code{ostream} inherit the generic methods from |
| @code{ios}, and in addition have the following methods available. |
| Declarations for this class come from @file{iostream.h}. |
| |
| @deftypefn Constructor {} ostream::ostream () |
| The simplest form of the constructor for an @code{ostream} simply |
| allocates a new @code{ios} object. |
| @end deftypefn |
| |
| @deftypefn Constructor {} ostream::ostream (streambuf* @var{sb} @w{[, ostream} @var{tie}]) |
| This alternative constructor requires a first argument @var{sb} of type |
| @code{streambuf*}, to use an existing open stream for output. It also |
| accepts an optional second argument @var{tie}, to specify a related |
| @code{ostream*} as the initial value for @code{ios::tie}. |
| |
| If you give the @code{ostream} a @code{streambuf} explicitly, using |
| this constructor, the @var{sb} is @emph{not} destroyed (or deleted or |
| closed) when the @code{ostream} is destroyed. |
| @end deftypefn |
| |
| @menu |
| * Writing:: Writing on an ostream. |
| * Output Position:: Repositioning an ostream. |
| * Ostream Housekeeping:: Miscellaneous ostream utilities. |
| @end menu |
| |
| @node Writing |
| @subsection Writing on an @code{ostream} |
| |
| These methods write on an @code{ostream} (you may also use the operator |
| @code{<<}; @pxref{Operators,,Operators and Default Streams}). |
| |
| @deftypefn Method ostream& ostream::put (char @var{c}) |
| Write the single character @var{c}. |
| @end deftypefn |
| |
| @deftypefn Method ostream& ostream::write (@var{string}, int @var{length}) |
| Write @var{length} characters of a string to this @code{ostream}, |
| beginning at the pointer @var{string}. |
| |
| @var{string} may have any of these types: @code{char*}, @code{unsigned |
| char*}, @code{signed char*}. |
| @end deftypefn |
| |
| @deftypefn Method ostream& ostream::form (const char *@var{format}, ...) |
| A @sc{gnu} extension, similar to @code{fprintf(@var{file}, |
| @var{format}, ...)}. |
| |
| @var{format} is a @code{printf}-style format control string, which is used |
| to format the (variable number of) arguments, printing the result on |
| this @code{ostream}. See @code{ostream::vform} for a version that uses |
| an argument list rather than a variable number of arguments. |
| @end deftypefn |
| |
| @deftypefn Method ostream& ostream::vform (const char *@var{format}, va_list @var{args}) |
| A @sc{gnu} extension, similar to @code{vfprintf(@var{file}, |
| @var{format}, @var{args})}. |
| |
| @var{format} is a @code{printf}-style format control string, which is used |
| to format the argument list @var{args}, printing the result on |
| this @code{ostream}. See @code{ostream::form} for a version that uses a |
| variable number of arguments rather than an argument list. |
| @end deftypefn |
| |
| @node Output Position |
| @subsection Repositioning an @code{ostream} |
| |
| You can control the output position (on output streams that actually |
| support positions, typically files) with these methods: |
| @c FIXME-future: sort out which classes support this and which |
| @c don't; fstream, filebuf? And what is failure condition when not supported? |
| |
| @deftypefn Method streampos ostream::tellp () |
| Return the current write position in the stream. |
| @end deftypefn |
| |
| @deftypefn Method ostream& ostream::seekp (streampos @var{loc}) |
| Reset the output position to @var{loc} (which is usually the result of a |
| previous call to @code{ostream::tellp}). @var{loc} specifies an |
| absolute position in the output stream. |
| @end deftypefn |
| |
| @deftypefn Method ostream& ostream::seekp (streamoff @var{loc}, @var{rel}) |
| @findex ios::seekdir |
| Reset the output position to @var{loc}, relative to the beginning, end, |
| or current output position in the stream, as indicated by @var{rel} (a |
| value from the enumeration @code{ios::seekdir}): |
| |
| @vtable @code |
| @item beg |
| Interpret @var{loc} as an absolute offset from the beginning of the |
| file. |
| |
| @item cur |
| Interpret @var{loc} as an offset relative to the current output |
| position. |
| |
| @item end |
| Interpret @var{loc} as an offset from the current end of the output |
| stream. |
| @end vtable |
| @end deftypefn |
| |
| @node Ostream Housekeeping |
| @subsection Miscellaneous @code{ostream} utilities |
| |
| You may need to use these @code{ostream} methods for housekeeping: |
| |
| @deftypefn Method ostream& flush () |
| Deliver any pending buffered output for this @code{ostream}. |
| @end deftypefn |
| |
| @deftypefn Method int ostream::opfx () |
| @code{opfx} is a @dfn{prefix} method for operations on @code{ostream} |
| objects; it is designed to be called before any further processing. See |
| @code{ostream::osfx} for the converse. |
| @c FIXME-future: specify sometime which methods start with opfx. |
| |
| @code{opfx} tests that the stream is in state @code{good}, and if so |
| flushes any stream tied to this one. |
| |
| The result is @code{1} when @code{opfx} succeeds; else (if the stream state is |
| not @code{good}), the result is @code{0}. |
| @end deftypefn |
| |
| @deftypefn Method void ostream::osfx () |
| @code{osfx} is a @dfn{suffix} method for operations on @code{ostream} |
| objects; it is designed to be called at the conclusion of any processing. All |
| the @code{ostream} methods end by calling @code{osfx}. See |
| @code{ostream::opfx} for the converse. |
| |
| If the @code{unitbuf} flag is set for this stream, @code{osfx} flushes |
| any buffered output for it. |
| |
| If the @code{stdio} flag is set for this stream, @code{osfx} flushes any |
| output buffered for the C output streams @file{stdout} and @file{stderr}. |
| @end deftypefn |
| |
| @node Istream |
| @section Managing input streams: class @code{istream} |
| |
| Class @code{istream} objects are specialized for input; as for |
| @code{ostream}, they are derived from @code{ios}, so you can use any of |
| the general-purpose methods from that base class. Declarations for this |
| class also come from @file{iostream.h}. |
| |
| @deftypefn Constructor {} istream::istream () |
| When used without arguments, the @code{istream} constructor simply |
| allocates a new @code{ios} object and initializes the input counter (the |
| value reported by @code{istream::gcount}) to @code{0}. |
| @end deftypefn |
| |
| @deftypefn Constructor {} istream::istream (streambuf *@var{sb} @w{[, ostream} @var{tie}]) |
| You can also call the constructor with one or two arguments. The first |
| argument @var{sb} is a @code{streambuf*}; if you supply this pointer, |
| the constructor uses that @code{streambuf} for input. |
| You can use the second optional argument @var{tie} to specify a related |
| output stream as the initial value for @code{ios::tie}. |
| |
| If you give the @code{istream} a @code{streambuf} explicitly, using |
| this constructor, the @var{sb} is @emph{not} destroyed (or deleted or |
| closed) when the @code{ostream} is destroyed. |
| @end deftypefn |
| |
| @menu |
| * Char Input:: Reading one character. |
| * String Input:: Reading strings. |
| * Input Position:: Repositioning an istream. |
| * Istream Housekeeping:: Miscellaneous istream utilities. |
| @end menu |
| |
| @node Char Input |
| @subsection Reading one character |
| |
| Use these methods to read a single character from the input stream: |
| |
| @deftypefn Method int istream::get () |
| Read a single character (or @code{EOF}) from the input stream, returning |
| it (coerced to an unsigned char) as the result. |
| @end deftypefn |
| |
| @deftypefn Method istream& istream::get (char& @var{c}) |
| Read a single character from the input stream, into @code{&@var{c}}. |
| @end deftypefn |
| |
| @deftypefn Method int istream::peek () |
| Return the next available input character, but @emph{without} changing |
| the current input position. |
| @end deftypefn |
| |
| @node String Input |
| @subsection Reading strings |
| |
| Use these methods to read strings (for example, a line at a time) from |
| the input stream: |
| |
| @deftypefn Method istream& istream::get (char* @var{c}, int @var{len} @w{[, char} @var{delim}]) |
| Read a string from the input stream, into the array at @var{c}. |
| |
| The remaining arguments limit how much to read: up to @samp{len-1} |
| characters, or up to (but not including) the first occurrence in the |
| input of a particular delimiter character @var{delim}---newline |
| (@code{\n}) by default. (Naturally, if the stream reaches end of file |
| first, that too will terminate reading.) |
| |
| If @var{delim} was present in the input, it remains available as if |
| unread; to discard it instead, see @code{iostream::getline}. |
| |
| @code{get} writes @samp{\0} at the end of the string, regardless |
| of which condition terminates the read. |
| @end deftypefn |
| |
| @deftypefn Method istream& istream::get (streambuf& @var{sb} @w{[, char} @var{delim}]) |
| Read characters from the input stream and copy them on the |
| @code{streambuf} object @var{sb}. Copying ends either just before the |
| next instance of the delimiter character @var{delim} (newline @code{\n} |
| by default), or when either stream ends. If @var{delim} was present in |
| the input, it remains available as if unread. |
| @end deftypefn |
| |
| @deftypefn Method istream& istream::getline (@var{charptr}, int @var{len} @w{[, char} @var{delim}]) |
| Read a line from the input stream, into the array at @var{charptr}. |
| @var{charptr} may be any of three kinds of pointer: @code{char*}, |
| @code{unsigned char*}, or @code{signed char*}. |
| |
| The remaining arguments limit how much to read: up to (but not |
| including) the first occurrence in the input of a line delimiter |
| character @var{delim}---newline (@code{\n}) by default, or up to |
| @samp{len-1} characters (or to end of file, if that happens sooner). |
| |
| If @code{getline} succeeds in reading a ``full line'', it also discards |
| the trailing delimiter character from the input stream. (To preserve it |
| as available input, see the similar form of @code{iostream::get}.) |
| |
| If @var{delim} was @emph{not} found before @var{len} characters or end |
| of file, @code{getline} sets the @code{ios::fail} flag, as well as the |
| @code{ios::eof} flag if appropriate. |
| |
| @code{getline} writes a null character at the end of the string, regardless |
| of which condition terminates the read. |
| @end deftypefn |
| |
| @deftypefn Method istream& istream::read (@var{pointer}, int @var{len}) |
| Read @var{len} bytes into the location at @var{pointer}, unless the |
| input ends first. |
| |
| @var{pointer} may be of type @code{char*}, @code{void*}, @code{unsigned |
| char*}, or @code{signed char*}. |
| |
| If the @code{istream} ends before reading @var{len} bytes, @code{read} |
| sets the @code{ios::fail} flag. |
| @end deftypefn |
| |
| @deftypefn Method istream& istream::gets (char **@var{s} @w{[, char} @var{delim}]) |
| A @sc{gnu} extension, to read an arbitrarily long string |
| from the current input position to the next instance of the @var{delim} |
| character (newline @code{\n} by default). |
| |
| To permit reading a string of arbitrary length, @code{gets} allocates |
| whatever memory is required. Notice that the first argument @var{s} is |
| an address to record a character pointer, rather than the pointer |
| itself. |
| @end deftypefn |
| |
| @deftypefn Method istream& istream::scan (const char *format ...) |
| A @sc{gnu} extension, similar to @code{fscanf(@var{file}, |
| @var{format}, ...)}. The @var{format} is a @code{scanf}-style format |
| control string, which is used to read the variables in the remainder of |
| the argument list from the @code{istream}. |
| @end deftypefn |
| |
| @deftypefn Method istream& istream::vscan (const char *format, va_list args) |
| Like @code{istream::scan}, but takes a single @code{va_list} argument. |
| @end deftypefn |
| |
| @node Input Position |
| @subsection Repositioning an @code{istream} |
| |
| Use these methods to control the current input position: |
| |
| @deftypefn Method streampos istream::tellg () |
| Return the current read position, so that you can save it and return to |
| it later with @code{istream::seekg}. |
| @end deftypefn |
| |
| @deftypefn Method istream& istream::seekg (streampos @var{p}) |
| Reset the input pointer (if the input device permits it) to @var{p}, |
| usually the result of an earlier call to @code{istream::tellg}. |
| @end deftypefn |
| |
| @deftypefn Method istream& istream::seekg (streamoff @var{offset}, ios::seek_dir @var{ref}) |
| Reset the input pointer (if the input device permits it) to @var{offset} |
| characters from the beginning of the input, the current position, or the |
| end of input. Specify how to interpret @var{offset} with one of these |
| values for the second argument: |
| |
| @vtable @code |
| @item ios::beg |
| Interpret @var{loc} as an absolute offset from the beginning of the |
| file. |
| |
| @item ios::cur |
| Interpret @var{loc} as an offset relative to the current output |
| position. |
| |
| @item ios::end |
| Interpret @var{loc} as an offset from the current end of the output |
| stream. |
| @end vtable |
| @end deftypefn |
| |
| @node Istream Housekeeping |
| @subsection Miscellaneous @code{istream} utilities |
| |
| Use these methods for housekeeping on @code{istream} objects: |
| |
| @deftypefn Method int istream::gcount () |
| Report how many characters were read from this @code{istream} in the |
| last unformatted input operation. |
| @c FIXME! Define "unformatted input" somewhere... |
| @end deftypefn |
| |
| @deftypefn Method int istream::ipfx (int @var{keepwhite}) |
| Ensure that the @code{istream} object is ready for reading; check for |
| errors and end of file and flush any tied stream. @code{ipfx} skips |
| whitespace if you specify @code{0} as the @var{keepwhite} |
| argument, @emph{and} @code{ios::skipws} is set for this stream. |
| |
| To avoid skipping whitespace (regardless of the @code{skipws} setting on |
| the stream), use @code{1} as the argument. |
| |
| Call @code{istream::ipfx} to simplify writing your own methods for reading |
| @code{istream} objects. |
| @end deftypefn |
| |
| @deftypefn Method void istream::isfx () |
| A placeholder for compliance with the draft @sc{ansi} standard; this |
| method does nothing whatever. |
| |
| If you wish to write portable standard-conforming code on @code{istream} |
| objects, call @code{isfx} after any operation that reads from an |
| @code{istream}; if @code{istream::ipfx} has any special effects that |
| must be cancelled when done, @code{istream::isfx} will cancel them. |
| @end deftypefn |
| |
| @deftypefn Method istream& istream::ignore ([int @var{n}] @w{[, int} @var{delim}]) |
| Discard some number of characters pending input. The first optional |
| argument @var{n} specifies how many characters to skip. The second |
| optional argument @var{delim} specifies a ``boundary'' character: |
| @code{ignore} returns immediately if this character appears in the |
| input. |
| |
| By default, @var{delim} is @code{EOF}; that is, if you do not specify a |
| second argument, only the count @var{n} restricts how much to ignore |
| (while input is still available). |
| |
| If you do not specify how many characters to ignore, @code{ignore} |
| returns after discarding only one character. |
| @end deftypefn |
| |
| @deftypefn Method istream& istream::putback (char @var{ch}) |
| Attempts to back up one character, replacing the character backed-up |
| over by @var{ch}. Returns @code{EOF} if this is not allowed. Putting |
| back the most recently read character is always allowed. (This method |
| corresponds to the C function @code{ungetc}.) |
| @end deftypefn |
| |
| @deftypefn Method istream& istream::unget () |
| Attempt to back up one character. |
| @end deftypefn |
| |
| @node Iostream |
| @section Input and output together: class @code{iostream} |
| |
| If you need to use the same stream for input and output, you can use an |
| object of the class @code{iostream}, which is derived from @emph{both} |
| @code{istream} and @code{ostream}. |
| |
| The constructors for @code{iostream} behave just like the constructors |
| for @code{istream}. |
| |
| @deftypefn Constructor {} iostream::iostream () |
| When used without arguments, the @code{iostream} constructor simply |
| allocates a new @code{ios} object, and initializes the input counter |
| (the value reported by @code{istream::gcount}) to @code{0}. |
| @end deftypefn |
| |
| @deftypefn Constructor {} iostream::iostream (streambuf* @var{sb} @w{[, ostream*} @var{tie}]) |
| You can also call a constructor with one or two arguments. The first |
| argument @var{sb} is a @code{streambuf*}; if you supply this pointer, |
| the constructor uses that @code{streambuf} for input and output. |
| |
| You can use the optional second argument @var{tie} (an @code{ostream*}) |
| to specify a related output stream as the initial value for |
| @code{ios::tie}. |
| @end deftypefn |
| |
| @cindex @code{iostream} destructor |
| @cindex destructor for @code{iostream} |
| As for @code{ostream} and @code{istream}, @code{iostream} simply uses |
| the @code{ios} destructor. However, an @code{iostream} is not deleted by |
| its destructor. |
| |
| You can use all the @code{istream}, @code{ostream}, and @code{ios} |
| methods with an @code{iostream} object. |
| |
| @node Files and Strings |
| @chapter Classes for Files and Strings |
| |
| There are two very common special cases of input and output: using files, |
| and using strings in memory. |
| |
| @code{libio} defines four specialized classes for these cases: |
| |
| @ftable @code |
| @item ifstream |
| Methods for reading files. |
| |
| @item ofstream |
| Methods for writing files. |
| |
| @item istrstream |
| Methods for reading strings from memory. |
| |
| @item ostrstream |
| Methods for writing strings in memory. |
| @end ftable |
| |
| @menu |
| * Files:: Reading and writing files. |
| * Strings:: Reading and writing strings in memory. |
| @end menu |
| |
| @node Files |
| @section Reading and writing files |
| |
| These methods are declared in @file{fstream.h}. |
| |
| @findex ifstream |
| @cindex class @code{ifstream} |
| You can read data from class @code{ifstream} with any operation from class |
| @code{istream}. There are also a few specialized facilities: |
| |
| @deftypefn Constructor {} ifstream::ifstream () |
| Make an @code{ifstream} associated with a new file for input. (If you |
| use this version of the constructor, you need to call |
| @code{ifstream::open} before actually reading anything) |
| @end deftypefn |
| |
| @deftypefn Constructor {} ifstream::ifstream (int @var{fd}) |
| Make an @code{ifstream} for reading from a file that was already open, |
| using file descriptor @var{fd}. (This constructor is compatible with |
| other versions of iostreams for @sc{posix} systems, but is not part of |
| the @sc{ansi} working paper.) |
| @end deftypefn |
| |
| @deftypefn Constructor {} ifstream::ifstream (const char* @var{fname} @w{[, int} @var{mode} @w{[, int} @var{prot}]]) |
| Open a file @code{*@var{fname}} for this @code{ifstream} object. |
| |
| By default, the file is opened for input (with @code{ios::in} as |
| @var{mode}). If you use this constructor, the file will be closed when |
| the @code{ifstream} is destroyed. |
| |
| You can use the optional argument @var{mode} to specify how to open the |
| file, by combining these enumerated values (with @samp{|} bitwise or). |
| (These values are actually defined in class @code{ios}, so that all |
| file-related streams may inherit them.) Only some of these modes are |
| defined in the latest draft @sc{ansi} specification; if portability is |
| important, you may wish to avoid the others. |
| |
| @vtable @code |
| @item ios::in |
| Open for input. (Included in @sc{ansi} draft.) |
| |
| @item ios::out |
| Open for output. (Included in @sc{ansi} draft.) |
| |
| @item ios::ate |
| Set the initial input (or output) position to the end of the file. |
| |
| @item ios::app |
| Seek to end of file before each write. (Included in @sc{ansi} draft.) |
| |
| @item ios::trunc |
| Guarantee a fresh file; discard any contents that were previously |
| associated with it. |
| |
| @item ios::nocreate |
| Guarantee an existing file; fail if the specified file did not already |
| exist. |
| |
| @item ios::noreplace |
| Guarantee a new file; fail if the specified file already existed. |
| |
| @item ios::bin |
| Open as a binary file (on systems where binary and text files have different |
| properties, typically how @samp{\n} is mapped; included in @sc{ansi} draft). |
| @end vtable |
| |
| @noindent |
| The last optional argument @var{prot} is specific to Unix-like systems; |
| it specifies the file protection (by default @samp{644}). |
| @end deftypefn |
| |
| @deftypefn Method void ifstream::open (const char* @var{fname} @w{[, int} @var{mode} @w{[, int} @var{prot}]]) |
| Open a file explicitly after the associated @code{ifstream} object |
| already exists (for instance, after using the default constructor). The |
| arguments, options and defaults all have the same meanings as in the |
| fully specified @code{ifstream} constructor. |
| @end deftypefn |
| |
| @findex ostream |
| @cindex class @code{ostream} |
| You can write data to class @code{ofstream} with any operation from class |
| @code{ostream}. There are also a few specialized facilities: |
| |
| @deftypefn Constructor {} ofstream::ofstream () |
| Make an @code{ofstream} associated with a new file for output. |
| @end deftypefn |
| |
| @deftypefn Constructor {} ofstream::ofstream (int @var{fd}) |
| Make an @code{ofstream} for writing to a file that was already open, |
| using file descriptor @var{fd}. |
| @end deftypefn |
| |
| @deftypefn Constructor {} ofstream::ofstream (const char* @var{fname} @w{[, int} @var{mode} @w{[, int} @var{prot}]]) |
| Open a file @code{*@var{fname}} for this @code{ofstream} object. |
| |
| By default, the file is opened for output (with @code{ios::out} as @var{mode}). |
| You can use the optional argument @var{mode} to specify how to open the |
| file, just as described for @code{ifstream::ifstream}. |
| |
| The last optional argument @var{prot} specifies the file protection (by |
| default @samp{644}). |
| @end deftypefn |
| |
| @deftypefn Destructor {} ofstream::~ofstream () |
| The files associated with @code{ofstream} objects are closed when the |
| corresponding object is destroyed. |
| @end deftypefn |
| |
| @deftypefn Method void ofstream::open (const char* @var{fname} @w{[, int} @var{mode} @w{[, int} @var{prot}]]) |
| Open a file explicitly after the associated @code{ofstream} object |
| already exists (for instance, after using the default constructor). The |
| arguments, options and defaults all have the same meanings as in the |
| fully specified @code{ofstream} constructor. |
| @end deftypefn |
| |
| @findex fstream |
| @cindex class @code{fstream} |
| The class @code{fstream} combines the facilities of @code{ifstream} and |
| @code{ofstream}, just as @code{iostream} combines @code{istream} and |
| @code{ostream}. |
| |
| @c FIXME-future: say something about fstream constructor, maybe. |
| |
| @findex fstreambase |
| @cindex class @code{fstreambase} |
| The class @code{fstreambase} underlies both @code{ifstream} and |
| @code{ofstream}. They both inherit this additional method: |
| |
| @deftypefn Method void fstreambase::close () |
| Close the file associated with this object, and set @code{ios::fail} in |
| this object to mark the event. |
| @end deftypefn |
| |
| @node Strings |
| @section Reading and writing in memory |
| |
| @c FIXME!! Per, there's a lot of guesswork here---please check carefully! |
| |
| @findex istrstream |
| @cindex class @code{istrstream} |
| @findex ostrstream |
| @cindex class @code{ostrstream} |
| @findex strstream |
| @cindex class @code{strstream} |
| @findex strstreambase |
| @cindex class @code{strstreambase} |
| @findex strstreambuf |
| @cindex class @code{strstreambuf} |
| The classes @code{istrstream}, @code{ostrstream}, and @code{strstream} |
| provide some additional features for reading and writing strings in |
| memory---both static strings, and dynamically allocated strings. The |
| underlying class @code{strstreambase} provides some features common to |
| all three; @code{strstreambuf} underlies that in turn. |
| |
| @c FIXME-future: Document strstreambuf methods one day, when we document |
| @c streambuf more fully. |
| |
| @deftypefn Constructor {} istrstream::istrstream (const char* @var{str} @w{[, int} @var{size}]) |
| Associate the new input string class @code{istrstream} with an existing |
| static string starting at @var{str}, of size @var{size}. If you do not |
| specify @var{size}, the string is treated as a @code{NUL} terminated string. |
| @end deftypefn |
| |
| @deftypefn Constructor {} ostrstream::ostrstream () |
| Create a new stream for output to a dynamically managed string, which |
| will grow as needed. |
| @end deftypefn |
| |
| @deftypefn Constructor {} ostrstream::ostrstream (char* @var{str}, int @var{size} [,int @var{mode}]) |
| A new stream for output to a statically defined string of length |
| @var{size}, starting at @var{str}. You may optionally specify one of |
| the modes described for @code{ifstream::ifstream}; if you do not specify |
| one, the new stream is simply open for output, with mode @code{ios::out}. |
| @end deftypefn |
| |
| @deftypefn Method int ostrstream::pcount () |
| Report the current length of the string associated with this @code{ostrstream}. |
| @end deftypefn |
| |
| @deftypefn Method char* ostrstream::str () |
| A pointer to the string managed by this @code{ostrstream}. Implies |
| @samp{ostrstream::freeze()}. |
| |
| Note that if you want the string to be nul-terminated, |
| you must do that yourself (perhaps by writing ends to the stream). |
| @end deftypefn |
| |
| @deftypefn Method void ostrstream::freeze ([int @var{n}]) |
| If @var{n} is nonzero (the default), declare that the string associated |
| with this @code{ostrstream} is not to change dynamically; while frozen, |
| it will not be reallocated if it needs more space, and it will not be |
| deallocated when the @code{ostrstream} is destroyed. Use |
| @samp{freeze(1)} if you refer to the string as a pointer after creating |
| it via @code{ostrstream} facilities. |
| |
| @samp{freeze(0)} cancels this declaration, allowing a dynamically |
| allocated string to be freed when its @code{ostrstream} is destroyed. |
| |
| If this @code{ostrstream} is already static---that is, if it was created |
| to manage an existing statically allocated string---@code{freeze} is |
| unnecessary, and has no effect. |
| @end deftypefn |
| |
| @deftypefn Method int ostrstream::frozen () |
| Test whether @code{freeze(1)} is in effect for this string. |
| @end deftypefn |
| |
| @deftypefn Method strstreambuf* strstreambase::rdbuf () |
| A pointer to the underlying @code{strstreambuf}. |
| @end deftypefn |
| |
| @node Streambuf |
| @chapter Using the @code{streambuf} Layer |
| |
| The @code{istream} and @code{ostream} classes are meant to handle |
| conversion between objects in your program and their textual representation. |
| |
| By contrast, the underlying @code{streambuf} class is for transferring |
| raw bytes between your program, and input sources or output sinks. |
| Different @code{streambuf} subclasses connect to different kinds of |
| sources and sinks. |
| |
| The @sc{gnu} implementation of @code{streambuf} is still evolving; we |
| describe only some of the highlights. |
| |
| @menu |
| * Areas:: Areas in a streambuf. |
| * Overflow:: Simple output re-direction |
| * Formatting:: C-style formatting for streambuf objects. |
| * Stdiobuf:: Wrappers for C stdio. |
| * Procbuf:: Reading/writing from/to a pipe |
| * Backing Up:: Marking and returning to a position. |
| * Indirectbuf:: Forwarding I/O activity. |
| @end menu |
| |
| @node Areas |
| @section Areas of a @code{streambuf} |
| |
| Streambuf buffer management is fairly sophisticated (this is a |
| nice way to say ``complicated''). The standard protocol |
| has the following ``areas'': |
| |
| @itemize @bullet |
| @item |
| @cindex put area |
| The @dfn{put area} contains characters waiting for output. |
| |
| @item |
| @cindex get area |
| The @dfn{get area} contains characters available for reading. |
| @end itemize |
| |
| The @sc{gnu} @code{streambuf} design extends this, but the details are |
| still evolving. |
| |
| The following methods are used to manipulate these areas. |
| These are all protected methods, which are intended to be |
| used by virtual function in classes derived from @code{streambuf}. |
| They are also all ANSI/ISO-standard, and the ugly names |
| are traditional. |
| (Note that if a pointer points to the 'end' of an area, |
| it means that it points to the character after the area.) |
| |
| @deftypefn Method char* streambuf::pbase () const |
| Returns a pointer to the start of the put area. |
| @end deftypefn |
| |
| @deftypefn Method char* streambuf::epptr () const |
| Returns a pointer to the end of the put area. |
| @end deftypefn |
| |
| @deftypefn Method char* streambuf::pptr () const |
| If @code{pptr() < epptr ()}, the @code{pptr()} |
| returns a pointer to the current put position. |
| (In that case, the next write will |
| overwrite @code{*pptr()}, and increment @code{pptr()}.) |
| Otherwise, there is no put position available |
| (and the next character written will cause @code{streambuf::overflow} |
| to be called). |
| @end deftypefn |
| |
| @deftypefn Method void streambuf::pbump (int @var{N}) |
| Add @var{N} to the current put pointer. |
| No error checking is done. |
| @end deftypefn |
| |
| @deftypefn Method void streambuf::setp (char* @var{P}, char* @var{E}) |
| Sets the start of the put area to @var{P}, the end of the put area to @var{E}, |
| and the current put pointer to @var{P} (also). |
| @end deftypefn |
| |
| @deftypefn Method char* streambuf::eback () const |
| Returns a pointer to the start of the get area. |
| @end deftypefn |
| |
| @deftypefn Method char* streambuf::egptr () const |
| Returns a pointer to the end of the get area. |
| @end deftypefn |
| |
| @deftypefn Method char* streambuf::gptr () const |
| If @code{gptr() < egptr ()}, then @code{gptr()} |
| returns a pointer to the current get position. |
| (In that case the next read will read @code{*gptr()}, |
| and possibly increment @code{gptr()}.) |
| Otherwise, there is no read position available |
| (and the next read will cause @code{streambuf::underflow} |
| to be called). |
| @end deftypefn |
| |
| @deftypefn Method void streambuf:gbump (int @var{N}) |
| Add @var{N} to the current get pointer. |
| No error checking is done. |
| @end deftypefn |
| |
| @deftypefn Method void streambuf::setg (char* @var{B}, char* @var{P}, char* @var{E}) |
| Sets the start of the get area to @var{B}, the end of the get area to @var{E}, |
| and the current put pointer to @var{P}. |
| @end deftypefn |
| |
| @node Overflow |
| @section Simple output re-direction by redefining @code{overflow} |
| |
| Suppose you have a function @code{write_to_window} that |
| writes characters to a @code{window} object. If you want to use the |
| ostream function to write to it, here is one (portable) way to do it. |
| This depends on the default buffering (if any). |
| |
| @cartouche |
| @smallexample |
| #include <iostream.h> |
| /* Returns number of characters successfully written to @var{win}. */ |
| extern int write_to_window (window* win, char* text, int length); |
| |
| class windowbuf : public streambuf @{ |
| window* win; |
| public: |
| windowbuf (window* w) @{ win = w; @} |
| int sync (); |
| int overflow (int ch); |
| // Defining xsputn is an optional optimization. |
| // (streamsize was recently added to ANSI C++, not portable yet.) |
| streamsize xsputn (char* text, streamsize n); |
| @}; |
| |
| int windowbuf::sync () |
| @{ streamsize n = pptr () - pbase (); |
| return (n && write_to_window (win, pbase (), n) != n) ? EOF : 0; |
| @} |
| |
| int windowbuf::overflow (int ch) |
| @{ streamsize n = pptr () - pbase (); |
| if (n && sync ()) |
| return EOF; |
| if (ch != EOF) |
| @{ |
| char cbuf[1]; |
| cbuf[0] = ch; |
| if (write_to_window (win, cbuf, 1) != 1) |
| return EOF; |
| @} |
| pbump (-n); // Reset pptr(). |
| return 0; |
| @} |
| |
| streamsize windowbuf::xsputn (char* text, streamsize n) |
| @{ return sync () == EOF ? 0 : write_to_window (win, text, n); @} |
| |
| int |
| main (int argc, char**argv) |
| @{ |
| window *win = ...; |
| windowbuf wbuf(win); |
| ostream wstr(&wbuf); |
| wstr << "Hello world!\n"; |
| @} |
| @end smallexample |
| @end cartouche |
| |
| |
| |
| @node Formatting |
| @section C-style formatting for @code{streambuf} objects |
| |
| The @sc{gnu} @code{streambuf} class supports @code{printf}-like |
| formatting and scanning. |
| |
| @deftypefn Method int streambuf::form (const char *@var{format}, ...) |
| Similar to @code{fprintf(@var{file}, @var{format}, ...)}. |
| The @var{format} is a @code{printf}-style format control string, which is used |
| to format the (variable number of) arguments, printing the result on |
| the @code{this} streambuf. The result is the number of characters printed. |
| @end deftypefn |
| |
| @deftypefn Method int streambuf::vform (const char *@var{format}, va_list @var{args}) |
| Similar to @code{vfprintf(@var{file}, @var{format}, @var{args})}. |
| The @var{format} is a @code{printf}-style format control string, which is used |
| to format the argument list @var{args}, printing the result on |
| the @code{this} streambuf. The result is the number of characters printed. |
| @end deftypefn |
| |
| @deftypefn Method int streambuf::scan (const char *@var{format}, ...) |
| Similar to @code{fscanf(@var{file}, @var{format}, ...)}. |
| The @var{format} is a @code{scanf}-style format control string, which is used |
| to read the (variable number of) arguments from the @code{this} streambuf. |
| The result is the number of items assigned, or @code{EOF} in case of |
| input failure before any conversion. |
| @end deftypefn |
| |
| @deftypefn Method int streambuf::vscan (const char *@var{format}, va_list @var{args}) |
| Like @code{streambuf::scan}, but takes a single @code{va_list} argument. |
| @end deftypefn |
| |
| @node Stdiobuf |
| @section Wrappers for C @code{stdio} |
| |
| A @dfn{stdiobuf} is a @code{streambuf} object that points to |
| a @code{FILE} object (as defined by @code{stdio.h}). |
| All @code{streambuf} operations on the @code{stdiobuf} are forwarded |
| to the @code{FILE}. Thus the @code{stdiobuf} object provides a |
| wrapper around a @code{FILE}, allowing use of @code{streambuf} |
| operations on a @code{FILE}. This can be useful when mixing |
| C code with C++ code. |
| |
| The pre-defined streams @code{cin}, @code{cout}, and @code{cerr} are |
| normally implemented as @code{stdiobuf} objects that point to |
| respectively @code{stdin}, @code{stdout}, and @code{stderr}. This is |
| convenient, but it does cost some extra overhead. |
| |
| If you set things up to use the implementation of @code{stdio} provided |
| with this library, then @code{cin}, @code{cout}, and @code{cerr} will be |
| set up to to use @code{stdiobuf} objects, since you get their benefits |
| for free. @xref{Stdio,,C Input and Output}. |
| |
| @ignore |
| @c FIXME-future: setbuf is not yet documented, hence this para is not useful. |
| Note that if you use @code{setbuf} to give a buffer to a @code{stdiobuf}, |
| that buffer will provide intermediate buffering in addition that |
| whatever is done by the @code{FILE}. |
| @end ignore |
| |
| @node Procbuf |
| @section Reading/writing from/to a pipe |
| |
| The @dfn{procbuf} class is a @sc{gnu} extension. It is derived from |
| @code{streambuf}. A @code{procbuf} can be @dfn{closed} (in which case |
| it does nothing), or @dfn{open} (in which case it allows communicating |
| through a pipe with some other program). |
| |
| @deftypefn Constructor {} procbuf::procbuf () |
| Creates a @code{procbuf} in a @dfn{closed} state. |
| @end deftypefn |
| |
| @deftypefn Method procbuf* procbuf::open (const char *@var{command}, int @var{mode}) |
| Uses the shell (@file{/bin/sh}) to run a program specified by @var{command}. |
| |
| If @var{mode} is @samp{ios::in}, standard output from the program is sent |
| to a pipe; you can read from the pipe by reading from the |
| @code{procbuf}. (This is similar to @w{@samp{popen(@var{command}, "r")}}.) |
| |
| If @var{mode} is @samp{ios::out}, output written written to the |
| @code{procbuf} is written to a pipe; the program is set up to read its |
| standard input from (the other end of) the pipe. (This is similar to |
| @w{@samp{popen(@var{command}, "w")}}.) |
| |
| The @code{procbuf} must start out in the @dfn{closed} state. |
| Returns @samp{*this} on success, and @samp{NULL} on failure. |
| @end deftypefn |
| |
| @deftypefn Constructor {} procbuf::procbuf (const char *@var{command}, int @var{mode}) |
| Calls @samp{procbuf::open (@var{command}, @var{mode})}. |
| @end deftypefn |
| |
| @deftypefn Method procbuf* procbuf::close () |
| Waits for the program to finish executing, |
| and then cleans up the resources used. |
| Returns @samp{*this} on success, and @samp{NULL} on failure. |
| @end deftypefn |
| |
| @deftypefn Destructor {} procbuf::~procbuf () |
| Calls @samp{procbuf::close}. |
| @end deftypefn |
| |
| @node Backing Up |
| @section Backing up |
| |
| The @sc{gnu} iostream library allows you to ask a @code{streambuf} to |
| remember the current position. This allows you to go back to this |
| position later, after reading further. You can back up arbitrary |
| amounts, even on unbuffered files or multiple buffers' worth, as long as |
| you tell the library in advance. This unbounded backup is very useful |
| for scanning and parsing applications. This example shows a typical |
| scenario: |
| |
| @cartouche |
| @smallexample |
| // Read either "dog", "hound", or "hounddog". |
| // If "dog" is found, return 1. |
| // If "hound" is found, return 2. |
| // If "hounddog" is found, return 3. |
| // If none of these are found, return -1. |
| int my_scan(streambuf* sb) |
| @{ |
| streammarker fence(sb); |
| char buffer[20]; |
| // Try reading "hounddog": |
| if (sb->sgetn(buffer, 8) == 8 |
| && strncmp(buffer, "hounddog", 8) == 0) |
| return 3; |
| // No, no "hounddog": Back up to 'fence' |
| sb->seekmark(fence); // |
| // ... and try reading "dog": |
| if (sb->sgetn(buffer, 3) == 3 |
| && strncmp(buffer, "dog", 3) == 0) |
| return 1; |
| // No, no "dog" either: Back up to 'fence' |
| sb->seekmark(fence); // |
| // ... and try reading "hound": |
| if (sb->sgetn(buffer, 5) == 5 |
| && strncmp(buffer, "hound", 5) == 0) |
| return 2; |
| // No, no "hound" either: Back up and signal failure. |
| sb->seekmark(fence); // Backup to 'fence' |
| return -1; |
| @} |
| @end smallexample |
| @end cartouche |
| |
| @deftypefn Constructor {} streammarker::streammarker (streambuf* @var{sbuf}) |
| Create a @code{streammarker} associated with @var{sbuf} |
| that remembers the current position of the get pointer. |
| @end deftypefn |
| |
| @deftypefn Method int streammarker::delta (streammarker& @var{mark2}) |
| Return the difference between the get positions corresponding |
| to @code{*this} and @var{mark2} (which must point into the same |
| @code{streambuffer} as @code{this}). |
| @end deftypefn |
| |
| @deftypefn Method int streammarker::delta () |
| Return the position relative to the streambuffer's current get position. |
| @end deftypefn |
| |
| @deftypefn Method int streambuf::seekmark (streammarker& @var{mark}) |
| Move the get pointer to where it (logically) was when @var{mark} |
| was constructed. |
| @end deftypefn |
| |
| @node Indirectbuf |
| @section Forwarding I/O activity |
| |
| An @dfn{indirectbuf} is one that forwards all of its I/O requests |
| to another streambuf. |
| |
| @ignore |
| @c FIXME-future: get_stream and put_stream are so far undocumented. |
| All get-related requests are sent to get_stream(). |
| All put-related requests are sent to put_stream(). |
| @end ignore |
| |
| An @code{indirectbuf} can be used to implement Common Lisp |
| synonym-streams and two-way-streams: |
| |
| @example |
| class synonymbuf : public indirectbuf @{ |
| Symbol *sym; |
| synonymbuf(Symbol *s) @{ sym = s; @} |
| virtual streambuf *lookup_stream(int mode) @{ |
| return coerce_to_streambuf(lookup_value(sym)); @} |
| @}; |
| @end example |
| |
| @node Stdio |
| @chapter C Input and Output |
| |
| @code{libio} is distributed with a complete implementation of the ANSI C |
| @code{stdio} facility. It is implemented using @code{streambuf} |
| objects. @xref{Stdiobuf,,Wrappers for C @code{stdio}}. |
| |
| The @code{stdio} package is intended as a replacement for the whatever |
| @code{stdio} is in your C library. |
| @ignore |
| @c FIXME-future: This is not useful unless we specify what problems. |
| It can co-exist with C libraries that have alternate implementations of |
| stdio, but there may be some problems. |
| @end ignore |
| Since @code{stdio} works best when you build @code{libc} to contain it, and |
| that may be inconvenient, it is not installed by default. |
| |
| Extensions beyond @sc{ansi}: |
| |
| @itemize @bullet |
| @item |
| A stdio @code{FILE} is identical to a streambuf. |
| Hence there is no need to worry about synchronizing C and C++ |
| input/output---they are by definition always synchronized. |
| |
| @item |
| If you create a new streambuf sub-class (in C++), you can use it as a |
| @code{FILE} from C. Thus the system is extensible using the standard |
| @code{streambuf} protocol. |
| |
| @item |
| You can arbitrarily mix reading and writing, without having to seek |
| in between. |
| |
| @item |
| Unbounded @code{ungetc()} buffer. |
| @end itemize |
| |
| @ignore |
| @c FIXME-future: Per says this is not ready to go public at v0.5 |
| @node Libio buffer management |
| @chapter Libio buffer management |
| |
| The libio user functions present an abstract sequence of characters, |
| that they read and write from. A number of buffers are used to go |
| between the user program and the abstract sequence. These buffers are |
| concrete arrays of characters that contain some sub-sequence of the |
| abstract sequence. |
| |
| The libio buffer management protocol is fairly complex. Its design is |
| based on the C++ @code{streambuf} protocol, so that the C++ |
| @code{streambuf} classes can be trivially implemented on top of the |
| libio protocol. |
| |
| The @dfn{write area} contains characters waiting for output. |
| |
| The @dfn{read area} contains characters available for reading. |
| |
| The @dfn{reserve area} is available to virtual methods. |
| Usually, the get and/or put areas are part of the reserve area. |
| |
| The @dfn{main get area} contains characters that have |
| been read in from the character source, but not yet |
| read by the application. |
| |
| The @dfn{backup area} contains previously read data that is being saved |
| because of a user request, or that have been "unread" (put back). |
| @end ignore |
| |
| @ignore |
| @c Per says this design is not finished |
| @node Streambuf internals |
| @chapter Streambuf internals |
| |
| @menu |
| * Buffer management:: |
| * Filebuf internals:: |
| @end menu |
| |
| @node Buffer management |
| @section Buffer management |
| |
| @subsection Areas |
| |
| NOTE: This chapter is due for an update. |
| |
| Streambuf buffer management is fairly sophisticated (this is a |
| nice way to say "complicated"). The standard protocol |
| has the following "areas": |
| |
| @itemize @bullet |
| @cindex put area |
| @item |
| The @dfn{put area} contains characters waiting for output. |
| @cindex get area |
| @item |
| The @dfn{get area} contains characters available for reading. |
| @cindex reserve area |
| @item |
| The @dfn{reserve area} is available to virtual methods. |
| Usually, the get and/or put areas are part of the reserve area. |
| @end itemize |
| |
| The @sc{gnu} @code{streambuf} design extends this by supporting two |
| get areas: |
| @itemize @bullet |
| @cindex main get area |
| @item |
| The @dfn{main get area} contains characters that have |
| been read in from the character source, but not yet |
| read by the application. |
| @cindex backup area |
| @item |
| The @dfn{backup area} contains previously read data that is being |
| saved because of a user request, or that have been "unread" (putback). |
| @end itemize |
| |
| The backup and the main get area are logically contiguous: That is, |
| the first character of the main get area follows the last character |
| of the backup area. |
| |
| The @dfn{current get area} is whichever one of the backup or |
| main get areas that is currently being read from. |
| The other of the two is the @dfn{non-current get area}. |
| |
| @subsection Pointers |
| |
| The following @code{char*} pointers define the various areas. |
| |
| @deftypefn Method char* streambuf::base () |
| The start of the reserve area. |
| @end deftypefn |
| |
| @deftypefn Method char* streambuf::ebuf () |
| The end of the reserve area. |
| @end deftypefn |
| |
| @deftypefn Method char* streambuf::Gbase () |
| The start of the main get area. |
| @end deftypefn |
| |
| @deftypefn Method char* streambuf::eGptr () |
| The end of the main get area. |
| @end deftypefn |
| |
| @deftypefn Method char* streambuf::Bbase () |
| The start of the backup area. |
| @end deftypefn |
| |
| @deftypefn Method char* streambuf::Bptr () |
| The start of the used part of the backup area. |
| The area (@code{Bptr()} .. @code{eBptr()}) contains data that has been |
| pushed back, while (@code{Bbase()} .. @code{eBptr()}) contains unused |
| space available for future putbacks. |
| @end deftypefn |
| |
| @deftypefn Method char* streambuf::eBptr () |
| The end of the backup area. |
| @end deftypefn |
| |
| @deftypefn Method char* streambuf::Nbase () |
| The start of the non-current get area (either @code{main_gbase} or @code{backup_gbase}). |
| @end deftypefn |
| |
| @deftypefn Method char* streambuf::eNptr () |
| The end of the non-current get area. |
| @end deftypefn |
| |
| @node Filebuf internals |
| @section Filebuf internals |
| |
| The @code{filebuf} is used a lot, so it is importamt that it be |
| efficient. It is also supports rather complex semantics. |
| so let us examine its implementation. |
| |
| @subsection Tied read and write pointers |
| |
| The streambuf model allows completely independent read and write pointers. |
| However, a @code{filebuf} has only a single logical pointer used |
| for both reads and writes. Since the @code{streambuf} protocol |
| uses @code{gptr()} for reading and @code{pptr()} for writing, |
| we map the logical file pointer into either @code{gptr()} or @code{pptr()} |
| at different times. |
| |
| @itemize @bullet |
| @item |
| Reading is allowed when @code{gptr() < egptr()}, which we call get mode. |
| |
| @item |
| Writing is allowed when @code{pptr() < epptr()}, which we call put mode. |
| @end itemize |
| |
| @noindent |
| A @code{filebuf} cannot be in get mode and put mode at the same time. |
| |
| We have up to two buffers: |
| |
| @itemize @bullet |
| @item |
| The backup area, defined by @code{Bbase()}, @code{Bptr()}, and @code{eBptr()}. |
| This can be empty. |
| |
| @item |
| The reserve area, which also contains the main get area. |
| For an unbuffered file, the (@code{shortbuf()}..@code{shortbuf()+1}) is used, |
| where @code{shortbuf()} points to a 1-byte buffer that is part of |
| the @code{filebuf}. |
| @end itemize |
| |
| @noindent |
| The file system's idea of the current position is @code{eGptr()}. |
| |
| Characters that have been written into a buffer but not yet written |
| out (flushed) to the file systems are those between @code{pbase()} |
| and @code{pptr()}. |
| |
| The end of the valid data bytes is: |
| @code{pptr() > eGptr() && pptr() < ebuf() ? pptr() : eGptr()}. |
| |
| If the @code{filebuf} is unbuffered or line buffered, |
| the @code{eptr()} is @code{pbase()}. This forces a call |
| to @code{overflow()} on each put of a character. |
| The logical @code{epptr()} is @code{epptr() ? ebuf() : NULL}. |
| (If the buffer is read-only, set @code{pbase()}, @code{pptr()}, |
| and @code{epptr()} to @code{NULL}. NOT!) |
| @end ignore |
| |
| @node Index |
| @unnumbered Index |
| @printindex cp |
| |
| @contents |
| @bye |