From 554fd8c5195424bdbcabf5de30fdc183aba391bd Mon Sep 17 00:00:00 2001 From: upstream source tree Date: Sun, 15 Mar 2015 20:14:05 -0400 Subject: obtained gcc-4.6.4.tar.bz2 from upstream website; verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository. --- libstdc++-v3/doc/html/manual/fstreams.html | 150 +++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 libstdc++-v3/doc/html/manual/fstreams.html (limited to 'libstdc++-v3/doc/html/manual/fstreams.html') diff --git a/libstdc++-v3/doc/html/manual/fstreams.html b/libstdc++-v3/doc/html/manual/fstreams.html new file mode 100644 index 000000000..6c03a2bb6 --- /dev/null +++ b/libstdc++-v3/doc/html/manual/fstreams.html @@ -0,0 +1,150 @@ + + +File Based Streams

+

So you want to copy a file quickly and easily, and most important, + completely portably. And since this is C++, you have an open + ifstream (call it IN) and an open ofstream (call it OUT): +

+   #include <fstream>
+
+   std::ifstream  IN ("input_file");
+   std::ofstream  OUT ("output_file"); 

Here's the easiest way to get it completely wrong: +

+   OUT << IN;

For those of you who don't already know why this doesn't work + (probably from having done it before), I invite you to quickly + create a simple text file called "input_file" containing + the sentence +

+      The quick brown fox jumped over the lazy dog.

surrounded by blank lines. Code it up and try it. The contents + of "output_file" may surprise you. +

Seriously, go do it. Get surprised, then come back. It's worth it. +

The thing to remember is that the basic_[io]stream classes + handle formatting, nothing else. In chaptericular, they break up on + whitespace. The actual reading, writing, and storing of data is + handled by the basic_streambuf family. Fortunately, the + operator<< is overloaded to take an ostream and + a pointer-to-streambuf, in order to help with just this kind of + "dump the data verbatim" situation. +

Why a pointer to streambuf and not just a streambuf? Well, + the [io]streams hold pointers (or references, depending on the + implementation) to their buffers, not the actual + buffers. This allows polymorphic behavior on the chapter of the buffers + as well as the streams themselves. The pointer is easily retrieved + using the rdbuf() member function. Therefore, the easiest + way to copy the file is: +

+   OUT << IN.rdbuf();

So what was happening with OUT<<IN? Undefined + behavior, since that chaptericular << isn't defined by the Standard. + I have seen instances where it is implemented, but the character + extraction process removes all the whitespace, leaving you with no + blank lines and only "Thequickbrownfox...". With + libraries that do not define that operator, IN (or one of IN's + member pointers) sometimes gets converted to a void*, and the output + file then contains a perfect text representation of a hexadecimal + address (quite a big surprise). Others don't compile at all. +

Also note that none of this is specific to o*f*streams. + The operators shown above are all defined in the parent + basic_ostream class and are therefore available with all possible + descendants. +

+

The first and most important thing to remember about binary I/O is + that opening a file with ios::binary is not, repeat + not, the only thing you have to do. It is not a silver + bullet, and will not allow you to use the <</>> + operators of the normal fstreams to do binary I/O. +

Sorry. Them's the breaks. +

This isn't going to try and be a complete tutorial on reading and + writing binary files (because "binary" + covers a lot of ground), but we will try and clear + up a couple of misconceptions and common errors. +

First, ios::binary has exactly one defined effect, no more + and no less. Normal text mode has to be concerned with the newline + characters, and the runtime system will translate between (for + example) '\n' and the appropriate end-of-line sequence (LF on Unix, + CRLF on DOS, CR on Macintosh, etc). (There are other things that + normal mode does, but that's the most obvious.) Opening a file in + binary mode disables this conversion, so reading a CRLF sequence + under Windows won't accidentally get mapped to a '\n' character, etc. + Binary mode is not supposed to suddenly give you a bitstream, and + if it is doing so in your program then you've discovered a bug in + your vendor's compiler (or some other chapter of the C++ implementation, + possibly the runtime system). +

Second, using << to write and >> to + read isn't going to work with the standard file stream classes, even + if you use skipws during reading. Why not? Because + ifstream and ofstream exist for the purpose of formatting, + not reading and writing. Their job is to interpret the data into + text characters, and that's exactly what you don't want to happen + during binary I/O. +

Third, using the get() and put()/write() member + functions still aren't guaranteed to help you. These are + "unformatted" I/O functions, but still character-based. + (This may or may not be what you want, see below.) +

Notice how all the problems here are due to the inappropriate use + of formatting functions and classes to perform something + which requires that formatting not be done? There are a + seemingly infinite number of solutions, and a few are listed here: +

How to go about using streambufs is a bit beyond the scope of this + document (at least for now), but while streambufs go a long way, + they still leave a couple of things up to you, the programmer. + As an example, byte ordering is completely between you and the + operating system, and you have to handle it yourself. +

Deriving a streambuf or filebuf + class from the standard ones, one that is specific to your data + types (or an abstraction thereof) is probably a good idea, and + lots of examples exist in journals and on Usenet. Using the + standard filebufs directly (either by declaring your own or by + using the pointer returned from an fstream's rdbuf()) + is certainly feasible as well. +

One area that causes problems is trying to do bit-by-bit operations + with filebufs. C++ is no different from C in this respect: I/O + must be done at the byte level. If you're trying to read or write + a few bits at a time, you're going about it the wrong way. You + must read/write an integral number of bytes and then process the + bytes. (For example, the streambuf functions take and return + variables of type int_type.) +

Another area of problems is opening text files in binary mode. + Generally, binary mode is intended for binary files, and opening + text files in binary mode means that you now have to deal with all of + those end-of-line and end-of-file problems that we mentioned before. +

+ An instructive thread from comp.lang.c++.moderated delved off into + this topic starting more or less at + this + post and continuing to the end of the thread. (The subject heading is "binary iostreams" on both comp.std.c++ + and comp.lang.c++.moderated.) Take special note of the replies by James Kanze and Dietmar Kühl. +

Briefly, the problems of byte ordering and type sizes mean that + the unformatted functions like ostream::put() and + istream::get() cannot safely be used to communicate + between arbitrary programs, or across a network, or from one + invocation of a program to another invocation of the same program + on a different platform, etc. +

-- cgit v1.2.3