Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
B.Eckel - Thinking in C++, Vol.2, 2nd edition.pdf
Скачиваний:
50
Добавлен:
08.05.2013
Размер:
2.09 Mб
Скачать

cout << in.rdbuf();

which causes the entire contents of the file to be sent to cout. This is not only more succinct to code, it is often more efficient than moving the bytes one at a time.

Using get( ) with a streambuf

There is a form of get( ) that allows you to write directly into the streambuf of another object. The first argument is the destination streambuf (whose address is mysteriously taken using a reference, discussed in Chapter XX), and the second is the terminating character, which stops the get( ) function. So yet another way to print a file to standard output is

//: C02:Sbufget.cpp

// Get directly into a streambuf #include "../require.h"

#include <fstream> #include <iostream> using namespace std;

int main() {

ifstream in("Sbufget.cpp"); assure(in, "Sbufget.cpp"); while(in.get(*cout.rdbuf()))

in.ignore(); } ///:~

rdbuf( ) returns a pointer, so it must be dereferenced to satisfy the function’s need to see an object. The get( ) function, remember, doesn’t pull the terminating character from the input stream, so it must be removed using ignore( ) so get( ) doesn’t just bonk up against the newline forever (which it will, otherwise).

You probably won’t need to use a technique like this very often, but it may be useful to know it exists.

Seeking in iostreams

Each type of iostream has a concept of where its “next” character will come from (if it’s an istream) or go (if it’s an ostream). In some situations you may want to move this stream position. You can do it using two models: One uses an absolute location in the stream called the streampos; the second works like the Standard C library functions fseek( ) for a file and moves a given number of bytes from the beginning, end, or current position in the file.

The streampos approach requires that you first call a “tell” function: tellp( ) for an ostream or tellg( ) for an istream. (The “p” refers to the “put pointer” and the “g” refers to the “get pointer.”) This function returns a streampos you can later use in the single-argument version

Chapter 14: Templates & Container Classes

78

of seekp( ) for an ostream or seekg( ) for an istream, when you want to return to that position in the stream.

The second approach is a relative seek and uses overloaded versions of seekp( ) and seekg( ). The first argument is the number of bytes to move: it may be positive or negative. The second argument is the seek direction:

ios::beg

From beginning of stream

 

 

ios::cur

Current position in stream

 

 

ios::end

From end of stream

 

 

Here’s an example that shows the movement through a file, but remember, you’re not limited to seeking within files, as you are with C and cstdio. With C++, you can seek in any type of iostream (although the behavior of cin & cout when seeking is undefined):

//: C02:Seeking.cpp

// Seeking in iostreams #include "../require.h" #include <iostream> #include <fstream> using namespace std;

int main(int argc, char* argv[]) { requireArgs(argc, 1);

ifstream in(argv[1]);

assure(in, argv[1]); // File must already exist in.seekg(0, ios::end); // End of file

streampos sp = in.tellg(); // Size of file cout << "file size = " << sp << endl; in.seekg(-sp/10, ios::end);

streampos sp2 = in.tellg();

in.seekg(0, ios::beg); // Start of file cout << in.rdbuf(); // Print whole file in.seekg(sp2); // Move to streampos

// Prints the last 1/10th of the file:

cout << endl << endl << in.rdbuf() << endl; } ///:~

This program picks a file name off the command line and opens it as an ifstream. assert( ) detects an open failure. Because this is a type of istream, seekg( ) is used to position the “get pointer.” The first call seeks zero bytes off the end of the file, that is, to the end. Because a streampos is a typedef for a long, calling tellg( ) at that point also returns the size of the file, which is printed out. Then a seek is performed moving the get pointer 1/10 the size of the file

– notice it’s a negative seek from the end of the file, so it backs up from the end. If you try to seek positively from the end of the file, the get pointer will just stay at the end. The

Chapter 14: Templates & Container Classes

79

streampos at that point is captured into sp2, then a seekg( ) is performed back to the beginning of the file so the whole thing can be printed out using the streambuf pointer produced with rdbuf( ). Finally, the overloaded version of seekg( ) is used with the streampos sp2 to move to the previous position, and the last portion of the file is printed out.

Creating read/write files

Now that you know about the streambuf and how to seek, you can understand how to create a stream object that will both read and write a file. The following code first creates an ifstream with flags that say it’s both an input and an output file. The compiler won’t let you write to an ifstream, however, so you need to create an ostream with the underlying stream buffer:

ifstream in("filename", ios::in|ios::out); ostream out(in.rdbuf());

You may wonder what happens when you write to one of these objects. Here’s an example:

//: C02:Iofile.cpp

// Reading & writing one file #include "../require.h" #include <iostream>

#include <fstream> using namespace std;

int main() {

ifstream in("Iofile.cpp"); assure(in, "Iofile.cpp"); ofstream out("Iofile.out"); assure(out, "Iofile.out");

out << in.rdbuf(); // Copy file in.close();

out.close();

// Open for reading and writing:

ifstream in2("Iofile.out", ios::in | ios::out); assure(in2, "Iofile.out");

ostream out2(in2.rdbuf());

cout << in2.rdbuf(); // Print whole file out2 << "Where does this end up?"; out2.seekp(0, ios::beg);

out2 << "And what about this?"; in2.seekg(0, ios::beg);

cout << in2.rdbuf(); } ///:~

Chapter 14: Templates & Container Classes

80

Соседние файлы в предмете Численные методы
  • #
    08.05.20133.99 Mб22A.Menezes, P.van Oorschot,S.Vanstone - HANDBOOK OF APPLIED CRYPTOGRAPHY.djvu
  • #
  • #
    08.05.20135.91 Mб24B.Eckel - Thinking in Java, 3rd edition (beta).pdf
  • #
  • #
    08.05.20136.09 Mб17D.MacKay - Information Theory, Inference, and Learning Algorithms.djvu
  • #
    08.05.20133.85 Mб15DIGITAL Visual Fortran ver.5.0 - Programmers Guide to Fortran.djvu
  • #
    08.05.20131.84 Mб12E.A.Lee, P.Varaiya - Structure and Interpretation of Signals and Systems.djvu