Читаем Thinking In C++. Volume 2: Practical Programming полностью

Remember that operator>>( ) returns its stream argument, so the while statement above tests the stream as a Boolean expression. This particular example assumes that the input stream myStream contains integers separated by white space. The function ios_base::operator void*( ) simply calls good( ) on its stream and returns the result.[41] Because most stream operations return their stream, using this idiom is convenient.

<p>Streams and exceptions</p>

Iostreams existed as part of C++ long before there were exceptions, so checking stream state manually was just the way things were done. For backward compatibility, this is still the status quo, but iostreams can throw exceptions instead. The exceptions( ) stream member function takes a parameter representing the state bits for which you want exceptions to be thrown. Whenever the stream encounters such a state, it throws an exception of type std::ios_base::failure, which inherits from std::exception.

Although you can trigger a failure exception for any of the four stream states, it’s not necessarily a good idea to enable exceptions for all of them. As Chapter 1 explains, use exceptions for truly exceptional conditions, but end-of-file is not only not exceptional—it’s expected! For that reason, you might want to enable exceptions only for the errors represented by badbit, which you would do like this:.

myStream.exceptions(ios::badbit);

You enable exceptions on a stream-by-stream basis, since exceptions( ) is a member function for streams. The exceptions( ) function returns a bitmask[42] (of type iostate, which is some compiler-dependent type convertible to int) indicating which stream states will cause exceptions. If those states have already been set, an exception is thrown immediately. Of course, if you use exceptions in connection with streams, you had better be ready to catch them, which means that you need to wrap all stream processing with a try block that has an ios::failure handler. Many programmers find this tedious and just check states manually where they expect errors to occur (since, for example, they don’t expect bad( ) to return true most of the time anyway). This is another reason that having streams throw exceptions is optional and not the default. In any case, you can choose how you want to handle stream errors.

<p>File iostreams</p>

Manipulating files with iostreams is much easier and safer than using stdio in C. All you do to open a file is create an object; the constructor does the work. You don’t have to explicitly close a file (although you can, using the close( ) member function) because the destructor will close it when the object goes out of scope. To create a file that defaults to input, make an ifstream object. To create one that defaults to output, make an ofstream object. An fstream object can do both input and output.

The file stream classes fit into the iostreams classes as shown in the following figure.

As before, the classes you actually use are template specializations defined by type definitions. For example, ifstream, which processes files of char, is defined as.

typedef basic_ifstream ifstream;

<p>A File-Processing Example</p>

Here’s an example that shows many of the features discussed so far. Notice the inclusion of to declare the file I/O classes. Although on many platforms this will also include automatically, compilers are not required to do so. If you want portable code, always include both headers.

//: C04:Strfile.cpp

// Stream I/O with files

// The difference between get() & getline()

#include

#include

#include "../require.h"

using namespace std;

int main() {

  const int sz = 100; // Buffer size;

  char buf[sz];

  {

    ifstream in("Strfile.cpp"); // Read

    assure(in, "Strfile.cpp"); // Verify open

    ofstream out("Strfile.out"); // Write

    assure(out, "Strfile.out");

    int i = 1; // Line counter

    // A less-convenient approach for line input:

    while(in.get(buf, sz)) { // Leaves \n in input

      in.get(); // Throw away next character (\n)

      cout << buf << endl; // Must add \n

      // File output just like standard I/O:

      out << i++ << ": " << buf << endl;

    }

  } // Destructors close in & out

  ifstream in("Strfile.out");

  assure(in, "Strfile.out");

  // More convenient line input:

  while(in.getline(buf, sz)) { // Removes \n

    char* cp = buf;

    while(*cp != ':')

      cp++;

    cp += 2; // Past ": "

    cout << cp << endl; // Must still add \n

  }

} ///:~

The creation of both the ifstream and ofstream are followed by an assure( ) to guarantee the file was successfully opened. Here again the object, used in a situation in which the compiler expects a Boolean result, produces a value that indicates success or failure.

Перейти на страницу:

Похожие книги

3ds Max 2008
3ds Max 2008

Одни уверены, что нет лучшего способа обучения 3ds Мах, чем прочитать хорошую книгу. Другие склоняются к тому, что эффективнее учиться у преподавателя, который показывает, что и как нужно делать. Данное издание объединяет оба подхода. Его цель – сделать освоение 3ds Мах 2008 максимально быстрым и результативным. Часто после изучения книги у читателя возникают вопросы, почему не получился тот или иной пример. Видеокурс – это гарантия, что такие вопросы не возникнут: ведь автор не только рассказывает, но и показывает, как нужно работать в 3ds Мах.В отличие от большинства интерактивных курсов, где работа в 3ds Мах иллюстрируется на кубиках-шариках, данный видеокурс полностью практический. Все приемы работы с инструментами 3ds Мах 2008 показаны на конкретных примерах, благодаря чему после просмотра курса читатель сможет самостоятельно выполнять даже сложные проекты.

Владимир Антонович Верстак , Владимир Верстак

Программирование, программы, базы данных / Программное обеспечение / Книги по IT