WIP on iostreams and namespaces

git-svn-id: https://cppannotations.svn.sourceforge.net/svnroot/cppannotations/trunk@262 f6dd340e-d3f9-0310-b409-bdd246841980
This commit is contained in:
Frank B. Brokken 2009-10-22 18:45:16 +00:00
parent 4af5bc87fd
commit 3812d933fc
14 changed files with 181 additions and 179 deletions

View file

@ -38,8 +38,6 @@ includefile(iostreams/output)
subsubsect(`ostream' flushing)
includefile(iostreams/ostreamflush)
COMMENT( >>>>>>>>>>> NEXT <<<<<<<<<<<<<)
lsubsect(OFSTREAM)(Output to files: the class `ofstream')
includefile(iostreams/ofstream)
@ -55,6 +53,9 @@ includefile(iostreams/input)
lsubsect(ISTREAM)(Basic input: the class `istream')
includefile(iostreams/istream)
COMMENT( >>>>>>>>>>> NEXT <<<<<<<<<<<<<)
lsubsubsect(ISTREAMREAD)(Reading from `istream' objects)
includefile(iostreams/istreamread)

View file

@ -185,7 +185,7 @@ tt(setstate). Its return type is tt(void). E.g.,
verb(
cin.setstate(ios::failbit); // set state to `fail'
)
To set multiple flags in one tt(setstate()) call use the tt(bit_or)
To set multiple flags in one tt(setstate()) call use the tt(bitor)
operator:
verb(
cin.setstate(ios::failbit | ios::eofbit))

View file

@ -1,7 +1,5 @@
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
using namespace std;
@ -9,23 +7,32 @@
{
ostringstream ostr("hello ", ios::ate);
cout << ostr.str() << endl;
cout << ostr.str() << '\n';
ostr.setf(ios::showbase);
ostr.setf(ios::hex, ios::basefield);
ostr << 12345;
cout << ostr.str() << endl;
cout << ostr.str() << '\n';
ostr << " -- ";
ostr.unsetf(ios::hex);
ostr << 12;
cout << ostr.str() << endl;
cout << ostr.str() << '\n';
ostr.str("new text");
cout << ostr.str() << '\n';
ostr.seekp(4, ios::beg);
ostr << "world";
cout << ostr.str() << '\n';
}
/*
Output from this program:
hello
hello 0x3039
hello 0x3039 -- 12
new text
new world
*/

View file

@ -32,7 +32,7 @@ particular flag was set, use the tt(bit_and) operator. Example:
itt(ios::fmtflags ios::flags(ios::fmtflags flagset)):
quote(the em(previous) set of flags are returned and the new set of
flags are defined by tt(flagset). Multiple flags are specified using the
tt(bit_or) operator. When setting flags using
tt(bitor) operator. When setting flags using
this member, a previously set. Example:
verb(
// change the representation to hexadecimal
@ -57,7 +57,7 @@ ref(FORMATFLAGS)). Manipulator: ti(setprecision). Example:
)
)
it() hi(setf)label(SETF)tt(ios::fmtflags ios::setf(ios::fmtflags flags)):
quote(sets one or more formatting flags (use the tt(bit_or)
quote(sets one or more formatting flags (use the tt(bitor)
operator to combine multiple flags). Already set flags are not affected. The
em(previous) set of flags is returned. Instead of using this member function
the manipulator ti(setiosflags) may be used. Examples are provided in the next

View file

@ -1,17 +1,17 @@
In bf(C++) i(input) is primarily based on the ti(istream) class. The
tt(istream) class defines the basic operators and members for extracting
information from streams: the emi(extraction operator) (rshift()), and
special members like tt(istream::read()) for reading unformatted information
from streams.
In bf(C++) i(input) is primarily based on the hi(istream)tt(std::istream)
class. The tt(istream) class defines the basic operators and members
extracting information from streams: the emi(extraction operator) (rshift()),
and special members like tt(istream::read) reading unformatted
information from streams.
From the class tt(istream) several other classes are derived, all having the
functionality of the tt(istream) class, and adding their own specialties. In
the next sections we will introduce:
The class tt(istream) acts as em(base class) for several other classes, all
offering the functionality of the tt(istream) class, but adding their own
specialties. In the upcoming sections we will introduce:
itemization(
it() The class tt(istream), offering the basic facilities for doing input;
it() The class ti(ifstream), allowing us to open files for reading
(comparable to bf(C)'s hi(fopen()) tt(fopen(filename, "r")));
it() The class ti(ifstream), allowing us to read files
(comparable to bf(C)'s hi(fopen) tt(fopen(filename, "r")));
it() The class ti(istringstream), allowing us to read information from
text that is not stored on files (streams) but in memory (comparable to
bf(C)'s ti(sscanf()) function).
bf(C)'s ti(sscanf) function).
)

View file

@ -1,22 +1,17 @@
The class ti(istream) is the I/O class defining basic input facilities. The
ti(cin) object is an tt(istream) object that is declared when sources contain
the i(preprocessor directive) ti(#include <iostream>). Note that
all facilities defined in the tt(ios) class are, as far as input is concerned,
available in the tt(istream) class as well due to the inheritance mechanism
(discussed in chapter ref(INHERITANCE)).
The class ti(istream) defines basic input facilities. The ti(cin) object, is
an tt(istream) object. All facilities related to input as defined by the
tt(ios) class are also available in the tt(istream) class.
tt(Istream) objects can be constructed using the following
emi(istream constructor):
We may define tt(istream) objects using the following
emi(istream constructor):
itemization(
itt(istream object(streambuf *sb)):
quote(this constructor can be used to construct a wrapper around
an existing open stream, based on an existing tt(streambuf), which may be the
interface to an existing file. Similarly to tt(ostream) objects, tt(istream)
objects may hi(std::istream: constructed using a 0-pointer) initially be
constructed using a 0-pointer. See section ref(OSTREAM) for a discussion, and
chapter ref(CONCRETE) for examples.)
an existing tt(std::streambuf) object. Similarly to tt(ostream) objects,
tt(istream) objects may be defined by passing it initially
hi(ostream: define using 0-pointer) a 0-pointer. See section ref(OSTREAM) for
a discussion, and chapter ref(CONCRETE) for examples.)
)
In order to use the tt(istream) class in bf(C++) sources, the
ti(#include <istream>) i(preprocessor directive) must be given. To use the
predefined tt(istream) object ti(cin), the ti(#include <iostream>)
preprocessor directive must be given.
To define the tt(istream) class in bf(C++) sources, the
ti(istream) header file must be included. To use the predefined
tt(istream) object ti(cin), the ti(iostream) header file must be included.

View file

@ -7,58 +7,65 @@ In order to use the tt(ofstream) class in bf(C++) sources, the
automatically make available the standard streams tt(cin), tt(cout) and
tt(cerr). Include ti(iostream) to declare these standard streams.
COMMENT( >>>>>>>>>>> NEXT <<<<<<<<<<<<<)
The following hi(ofstream constructors) constructors are available for
tt(ofstream) objects:
itemization(
itt(ofstream object):
quote(This is the basic constructor. It creates
an tt(ofstream) object which may be associated with an actual file later,
using the tt(open()) member (see below).)
itt(ofstream object(char const *name, int mode)):
quote( This constructor can be used to associate an tt(ofstream)
object with the file named tt(name) using output mode tt(mode). The
emi(output mode) is by default ti(ios::out). See section ref(OUTPUTMODES) for
a complete overview of available output modes.
In the following example an tt(ofstream) object, associated with the newly
created file tt(/tmp/scratch), is constructed:
itt(ofstream object):
quote(this is the basic constructor. It defines an tt(ofstream) object
which may be associated with an actual file later, using the tt(open()) member
(see below).
)
itt(ofstream object(char const *name, ios::openmode mode = ios::out)):
quote(this constructor can be used to define an tt(ofstream) object
and associate it immediately with the file named tt(name) using output mode
tt(mode). Section ref(OUTPUTMODES) provides an overview of available output
modes. Example:
verb(
ofstream out("/tmp/scratch");
)
)
)
Note that it is not possible to open a tt(ofstream) using a
Note that it is not possible to open an tt(ofstream) using a
emi(file descriptor). The reason for this is (apparently) that file
descriptors are not universally available over different operating systems.
Fortunately, file descriptors can be used (indirectly) with a ti(streambuf)
object (and in some implementations: with a ti(filebuf) object, which is also
a tt(streambuf)). tt(Streambuf) objects are discussed in section
ref(STREAMBUF), tt(filebuf) objects are discussed in section ref(FILEBUF).
Fortunately, file descriptors can be used (indirectly) with a
tt(std::streambuf) object (and in some implementations: with a
tt(std::filebuf) object, which is also a tt(streambuf)). tt(Streambuf) objects
are discussed in section ref(STREAMBUF), tt(filebuf) objects are discussed in
section ref(FILEBUF).
Instead of directly associating an tt(ofstream) object with a file, the
object can be constructed first, and opened later.
itemization(
ithtq(ofstream::open())
(void ofstream::open(char const *name, ios::openmode mode))
(Having constructed an tt(ofstream) object, the member
function tt(open()) can be used to associate the tt(ofstream) object
with an actual file.)
iti(ofstream::close()):
quote(Conversely, it is possible to close an tt(ofstream) object
explicitly using the tt(close()) member function. The function sets the
ti(ios::fail) flag of the closed object. Closing the file will flush any
buffered information to the associated file. A file is hi(closing streams)
automatically closed when the associated tt(ofstream) object ceases to exist.)
)
A subtlety is the following: Assume a stream is constructed, but it is not
actually attached to a file. E.g., the statement tt(ofstream ostr) was
executed. When we now check its status through tt(good()), a non-zero (i.e.,
em(OK)) value will be returned. The `good' status here indicates that the
stream object has been properly constructed. It doesn't mean the file is also
open. To test whether a stream is actually open, hi(testing the `open' status)
inspect hi(is_open) tt(ofstream::is_open()): If ti(true), the stream is
open. See the following example:
ithtq(open)(void ofstream::open(char const *name,
ios::openmode mode = ios::out))
(this member function is used to associate an tt(ofstream) object with
an actual file. If the tt(ios::fail) flag was set before calling tt(open) and
opening succeeds the flag is cleared. Opening an already open stream fails. To
reassociate a stream with another file it must first be closed:
verb(
ofstream out("/tmp/out");
out << "hello\n";
out.close(); // flushes and closes out
out.open("/tmp/out2");
out << "world\n";
)
)
ithtq(close)(void ofstream::close())
(an tt(ofstream) object is closed by this member function. The
function sets the ti(ios::fail) flag of the closed object. Closing the file
will flush any buffered information to the associated file. A file is
automatically closed when the associated tt(ofstream) object ceases to exist.
)
ithtq(is_open)(bool ofstream::is_open() const))
(assume a stream was properly constructed, but it has not yet been
attached to a file. E.g., the statement tt(ofstream ostr) was executed. When
we now check its status through tt(good()), a non-zero (i.e., em(OK)) value is
be returned. The `good' status here indicates that the stream object has been
constructed properly. It doesn't mean the file is also open. To test whether a
stream is actually open, tt(is_open) should be called. If it returns ti(true),
the stream is open. Example:
verbinclude(iostreams/examples/isopen.cc)
)
)

View file

@ -22,7 +22,7 @@ is inserted into it), but it may be given a tt(streambuf) later. Thus it may
be preliminary constructed, suspending its use until an appropriate
tt(streambuf) becomes available.
)
In order to define the tt(ostream) class in bf(C++) sources, the
To define the tt(ostream) class in bf(C++) sources, the
ti(ostream) header file must be included. To use the predefined
tt(ostream) objects (tt(std::cin, std::cout) etc.) the ti(iostream) header
must be included.

View file

@ -1,48 +1,39 @@
In order to hi(write to memory) write information to memory using the
tt(stream) facilities, ti(ostringstream) objects can be used. These objects
are derived from tt(ostream) objects. The following constructors and members
are available:
In order to hi(streams: writing to memory) write information to memory using
tt(stream) facilities, hi(ostringstream)tt(std::ostringstream) objects should
be used. As the class tt(ostringstream) is derived from the class tt(ostream)
all tt(ostream)'s facilities are available to tt(ostringstream) objects as
well. In addition the class tt(ostringstream) offers the following
constructors and members:
itemization(
ithtq(ostringstream constructors)
(ostringstream ostr(string const &s, ios::openmode mode))
(When using this constructor, the last or both arguments may be
omitted. There is also a constructor requiring only an ti(openmode)
parameter. If tt(string s) is specified and tt(openmode) is tt(ios::ate), the
tt(ostringstream) object is initialized with the tt(string s) and remaining
insertions are appended to the contents of the tt(ostringstream) object. If
tt(string s) is provided, it will not be altered, as any information inserted
into the object is stored in dynamically allocated memory which is deleted
when the tt(ostringstream) object goes out of scope.)
itht(ostringstream::str())(string ostringstream::str() const):
quote(This member function will return the string that is stored
inside the tt(ostringstream) object.)
itht(ostringstream::str(string))(ostringstream::str(string)):
quote(This member function will re-initialize the
tt(ostringstream) object with new initial contents.)
ithtq(ostringstream)
(ostringstream ostr(string const &init,
ios::openmode mode = ios::out))
(the argument may be omitted. If tt(string init) was specified
and tt(openmode) is tt(ios::ate), the tt(ostringstream) object is initialized
by the tt(string init) and remaining insertions are appended to the contents
of the tt(ostringstream) object.
)
itt(ostringstream ostr(ios::openmode mode = ios::out))
(this constructor can also be used as default
constructor. Alternatively it allows, e.g., forced additions at the end of the
information stored in the object so far (using tt(ios::app)). Example:
verb(
std::ostringstream out;
)
)
ithtq(str)(std::string ostringstream::str() const)
(a copy of the string that is stored inside the tt(ostringstream)
object is returned.)
itt(void ostringstream::str(std::string const &str))
(the current object is reinitialized with new initial contents.)
)
Before the tt(stringstream) class was available the class ti(ostrstream)
was commonly used for doing output to memory. This latter class suffered from
the fact that, once its contents were retrieved using its tt(str()) member
function, these contents were `frozen', meaning that its dynamically allocated
memory was not released when the object went out of scope. Although this
situation could be prevented (using the tt(ostrstream) member call
ti(freeze(0))), this implementation could easily lead to hi(memory leak)
em(memory leaks). The tt(stringstream) class does not suffer from these
risks. Therefore, the use of the class tt(ostrstream) is now deprecated in
favor of tt(ostringstream).
The following example illustrates the use of the tt(ostringstream) class:
several values are inserted into the object. Then, the stored text is stored
in a string, whose length and contents are thereupon printed. Such
tt(ostringstream) objects are most often used for doing `type to string'
i(conversions), like converting tt(int) to tt(string). Formatting commands
can be used with tt(stringstreams) as well, as they are available in
tt(ostream) objects.
COMMENT(
It should also be possible to perform em(seek)
operations with tt(ostringstream) objects, but the current i(Gnu) i(g++)
(version 3.0) implementation apparently does not support them.
END)
Here is an
example showing the use of an tt(ostringstream) object:
several values are inserted into the object. Then, the text contained by the
tt(ostringstream) object is stored in a tt(std::string), whose length and
contents are thereupon printed. Such tt(ostringstream) objects are most often
used for doing `type to string'hi(conversions: binary to text) conversions,
like converting tt(int) values to text. Formatting flags can be used with
tt(ostringstreams) as well, as they are part of tt(ostream) objects.
Here is an example showing an tt(ostringstream) object being used:
verbinclude(iostreams/examples/ostringstream.cc)

View file

@ -1,46 +1,43 @@
The following i(file modes) or i(file flags) are defined for constructing or
opening tt(ofstream) (or tt(istream), see section ref(IFSTREAM)) objects. The
values are of type ti(ios::openmode):
The following i(file modes) or i(file flags) are available when constructing
or opening tt(ofstream) (or tt(istream), see section ref(IFSTREAM))
objects. The values are of type hi(openmode)tt(ios::openmode). Flags may be
combined using the tt(bitor) operator.
itemization(
iti(ios::app):
quote( reposition to the end of the file before every output
command. The existing contents of the file are kept.)
iti(ios::ate):
quote(Start initially at the end of the file. The existing
contents of the file are kept.nl()
Note that the original contents are em(only) kept if some other flag tells
the object to do so. For example tt(ofstream out("gone", ios::ate)) will
hi(ios::ate: file rewritten)
ithtq(app)(ios::app)
(reposition the stream to its end before every output command. The
file is created if it doesn't yet exist. When opening a stream in this mode
any existing contents of the file are kept.)
ithtq(ate)(ios::ate)
(start initially at the end of the file. Note that any existing
contents are em(only) kept if some other flag tells the object to do so. For
example tt(ofstream out("gone", ios::ate)) will
em(rewrite) the file tt(gone), because the implied tt(ios::out) will cause
the rewriting. If rewriting of an existing file should be prevented, the
tt(ios::in) hi(ios::in: and std::ofstream) mode should be specified too. Note
that in this case the construction only succeeds if the file already exists.)
iti(ios::binary):
quote(open a i(binary file) (used on systems which make a
distinction between text- and binary files, like i(MS-DOS) or i(MS-Windows)).)
iti(ios::in):
quote( open the file for reading. The file must exist.)
iti(ios::out):
quote( open the file. Create it if it doesn't yet exist. If it
exists, the i(file is rewritten).)
iti(ios::trunc):
quote(Start initially with an empty file. Any existing contents
of the file are lost.)
tt(ios::in) hi(in)hi(file rewriting: preventing) mode should be specified
too. However, when tt(ios::in) is specified the file must already exist.)
ithtq(binary)(ios::binary)
(open a file in hi(file: binary mode)binary mode (used on systems
distinguishing text- and binary files, like i(MS-Windows)).
)
ithtq(in)(ios::in)
(open the file for reading. The file must exist.)
ithtq(out)(ios::out)
(open the file for writing. Create it if it doesn't yet exist. If
it exists, the i(file is rewritten).)
ithtq(trunc)(ios::trunc)
(start initially with an empty file. Any existing contents of the
file are lost.)
)
The following combinations of file flags have special meanings:
verb(
out | app: The file is created if non-existing,
information is always added to the end of the
stream;
out | trunc: The file is (re)created empty to be written;
in | out: The stream may be read and written. However, the
file must exist.
in | out | trunc: The stream may be read and written. It is
(re)created empty first.
)
An interesting subtlety is that the tt(open()) members of the tt(ifstream,
ofstream) and tt(fstream) classes show tt(ios::openmode) as
the type of their second parameter. In contrast to this, the tt(bitor)
operator returns an tt(int) when applied to two enum-values. The question why
the tt(bitor) operator is accepted here will be answered in a later chapter
(chapter ref(OperatorOverloading), section ref(EnumOverload)).
An interesting subtlety is that the tt(open) members of the tt(ifstream,
ofstream) and tt(fstream) classes have a second parameter of type
tt(ios::openmode). In contrast to this, the tt(bitor) operator returns an
tt(int) when applied to two enum-values. The question why the tt(bitor)
operator may nevertheless be used here is answered in a later chapter
(cf. section ref(EnumOverload)).

View file

@ -4,7 +4,7 @@ information into streams: the emi(insertion operator) (lshift()), and special
members like tt(write) writing unformatted information to streams.
The class tt(ostream) acts as em(base class) for several other classes, all
having the functionality of the tt(ostream) class, but adding their own
offering the functionality of the tt(ostream) class, but adding their own
specialties. In the upcoming sections we will introduce:
itemization(
it() The class tt(ostream), offering the basic output facilities;

View file

@ -1,4 +1,3 @@
COMMENT(>>>>>>>>>>>>> NEXT <<<<<<<<<<<<<)
lsect(Namespaces)(Namespaces)
includefile(namespaces/intro)
@ -6,6 +5,8 @@ includefile(namespaces/intro)
subsect(Defining namespaces)
includefile(namespaces/defining)
COMMENT(>>>>>>>>>>>>> NEXT <<<<<<<<<<<<<)
subsubsect(Declaring entities in namespaces)
includefile(namespaces/declaring)
@ -21,7 +22,7 @@ includefile(namespaces/intro)
subsubsect(`Koenig lookup')
includefile(namespaces/koenig)
subsect(The standard namespace)
subsect(The standard namespace) COMMENT(RESERVED BY C++)
includefile(namespaces/std)
subsect(Nesting namespaces and namespace aliasing)

View file

@ -6,19 +6,18 @@ Namespaces are defined according to the following syntax:
// (declarative region)
}
)
The identifier used in the definition of a namespace is a standard bf(C++)
The identifier used when defining a namespace is a standard bf(C++)
identifier.
Within the emi(declarative region), introduced in the above code
example, functions, variables, structs, classes and even (nested) namespaces
can be defined or declared. Namespaces cannot be defined within a block. So it
is not possible to define a namespace within, e.g., a function. However, it is
possible to define a namespace using multiple em(namespace)
declarations. Namespaces are called `em(open)'. This means that a namespace
tt(CppAnnotations) could be defined in a file tt(file1.cc) and also in a file
tt(file2.cc). The entities defined in the tt(CppAnnotations) namespace of
files tt(file1.cc) and tt(file2.cc) are then united in one tt(CppAnnotations)
namespace region. For example:
Within the emi(declarative region), introduced in the above code example,
functions, variables, structs, classes and even (nested) namespaces can be
defined or declared. Namespaces cannot be defined within a function
body. However, it is possible to define a namespace using multiple
em(namespace) declarations. Namespaces are `em(open)' meaning that
a namespace tt(CppAnnotations) could be defined in a file tt(file1.cc) and
also in a file tt(file2.cc). Entities defined in the tt(CppAnnotations)
namespace of files tt(file1.cc) and tt(file2.cc) are then united in one
tt(CppAnnotations) namespace region. For example:
verb(
// in file1.cc
namespace CppAnnotations
@ -38,8 +37,12 @@ namespace region. For example:
}
}
)
Both tt(sin()) and tt(cos()) are now defined in the same
Both tt(sin) and tt(cos) are now defined in the same
tt(CppAnnotations) namespace.
Namespace entities can be defined outside of their namespaces. This
topic is discussed in section ref(OUTSIDE).

View file

@ -1,18 +1,18 @@
Imagine a math teacher who wants to develop an interactive math program. For
this program functions like tt(cos(), sin(), tan()) etc. are to be used
this program functions like tt(cos, sin, tan) etc. are to be used
accepting arguments in degrees rather than arguments in
radians. Unfortunately, the function name tt(cos()) is already in use, and that
radians. Unfortunately, the function name tt(cos) is already in use, and that
function accepts radians as its arguments, rather than degrees.
Problems like these are usually solved by defining another name, e.g., the
function name tt(cosDegrees()) is defined. bf(C++) offers an alternative
solution: by allowing us to use emi(namespaces). Namespaces can be considered
as areas or regions in the code in which identifiers are defined which
function name tt(cosDegrees) is defined. bf(C++) offers an alternative
solution through emi(namespaces). Namespaces can be considered
as areas or regions in the code in which identifiers are defined that
normally won't conflict with names already defined elsewhere.
Now that the i(ANSI/ISO) standard has been implemented to a large degree in
recent compilers, the use of namespaces is more strictly enforced than in
previous versions of compilers. This has certain consequences for the setup of
previous versions of compilers. This affects the setup of
ti(class) i(header files). At this point in the Annotations this cannot be
discussed in detail, but in section ref(NAMESPACEHDR) the construction of
header files using entities from namespaces is discussed.