Бьерн Страуструп - Язык программирования С++. Главы 9-10
Страница 39. Файлы и потоки



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

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

     #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 есть
отдельные позиции для чтения и записи.

 
« Предыдущая статья   Следующая статья »