Язык программирования C++ от Страуструпа

       

Файлы и потоки


Ниже приведена программа копирования одного файла в другой. Имена файлов берутся из командной строки программы:

#include <fstream.h>

#include <libc.h>

void error(char* s, char* s2 ="")

{

  cerr << s << ' ' << s2 << '\n';

  exit(1);

}

int main(int argc, char* argv[])

{

  if (argc != 3) error("wrong number of arguments");

  ifstream from(argv[1]);

  if (!from) error("cannot open input file",argv[1]);



  ostream to(argv[2]);

  if (!to) error("cannot open output file",argv[2]);

  char ch;

  while (from.get(ch)) to.put(ch);

  if (!from.eof() || to.bad())

     error("something strange happened");

  return 0;

}

Для открытия выходного файла создается объект класса ofstream - выходной поток файла, использующий в качестве аргумента имя файла. Аналогично, для открытия входного файла создается объект класса ifstream - входной файловый поток, также использующий в качестве аргумента имя файла. В обоих случаях следует  проверить состояние созданного объекта, чтобы убедиться в успешном открытии файла, а если это не так, операции завершатся не успешно, но корректно.

По умолчанию ifstream всегда открывается на чтение, а ofstream открывается на запись. В ostream и в istream можно использовать необязательный второй аргумент, указывающий иные режимы открытия:

class ios {

  public:

     //...

     enum open_mode {

       in=1,                       // открыть на чтение

       out=2,                      // открыть как выходной

       ate=4,                      // открыть и переместиться в конец файла

       app=010,                    // добавить

       trunc=020,                  // сократить файл до нулевой длины

       nocreate=040,               // неудача, если файл не существует

       noreplace=0100              // неудача, если файл существует

     };

     //...

};

Настоящие значения для open_mode и их смысл вероятно будут зависеть от реализации. Будьте добры, за деталями обратитесь к руководству по вашей библиотеке или экспериментируйте. Приведенные комментарии могут прояснить их назначение. Например, можно открыть файл с условием, что операция открытия не выполнится, если файл уже не существует:

void f()

{

  ofstream mystream(name,ios::out|ios::nocreate);

  if (ofstream.bad()) {

     //...

  }

  //...

}

Также можно открыть файл сразу на чтение и запись:

fstream dictionary("concordance", ios::in|ios::out);

Все операции, допустимые для ostream и ostream, можно применять к fstream. На самом деле, класс fstream является производным от iostream, который является, в свою очередь, производным от istream и ostream. Причина, по которой информация по буферизации и форматированию для ostream и istream находится в виртуальном базовом классе ios, в том, чтобы заставить действовать всю эту последовательность производных классов. По этой же причине операции позиционирования в istream и ostream имеют разные имена - seekp() и seekg(). В iostream есть отдельные позиции для чтения и записи.



Содержание раздела