Выбрать главу

 while(in) {

  /* При достижении конца файла потоковый объект in примет значение false. */

  in.get(ch);

  if(in) cout << ch;

 }

 in.close();

 return 0;

}

При достижении конца файла потоковый объект in примет значение ЛОЖЬ, которое остановит выполнение цикла while.

Существует более короткий вариант цикла, предназначенного для считывания и отображения содержимого файла.

while(in.get(ch)) cout << ch;

Этот вариант также имеет право на существование, поскольку функция get() возвращает потоковый объект in, который при достижении конца файла примет значение false.

В следующей программе для записи строки в файл используется функция put().

/* Использование функции put() для записи строки в файл.

*/

#include <iostream>

#include <fstream>

using namespace std;

int main()

{

 char *p = "Всем привет!";

 ofstream out("test", ios::out | ios::binary);

 if(!out) {

  cout << "He удается открыть файл.\n";

  return 1;

 }

 while(*p) out.put(*p++);

 out.close();

 return 0;

}

Считывание и запись в файл блоков данных

Чтобы считывать и записывать в файл блоки двоичных данных, используйте функции-члены read() и write(). Их прототипы имеют следующий вид.

istream &read(char *buf, streamsize num);

ostream &write(const char *buf, int streamsize num);

Функция read() считывает num байт данных из связанного с файлом потока и помещает их в буфер, адресуемый параметром buf. Функция write() записывает num байт данных в связанный с файлом поток из буфера, адресуемого параметром buf. Как упоминалось выше, тип streamsize определен как некоторая разновидность целочисленного типа. Он позволяет хранить самое большое количество байтов, которое может быть передано в процессе любой операции ввода-вывода.

Функция read() вводит блок данных, а функция write() выводит его.

При выполнении следующей программы сначала в файл записывается массив целых чисел, а затем он же считывается из файла.

// Использование функций read() и write().

#include <iostream>

#include <fstream>

using namespace std;

int main()

{

 int n[5] = {1, 2, 3, 4, 5};

 register int i;

 ofstream out("test", ios::out | ios::binary);

 if(!out) {

  cout << "He удается открыть файл.\n";

  return 1;

 }

 out.write((char *) &n, sizeof n);

 out.close();

 for(i=0; i<5; i++) // очищаем массив

  n[i] = 0;

 ifstream in ("test", ios::in | ios::binary);

 if(!in) {

  cout << "He удается открыть файл.\n";

  return 1;

 }

 in.read((char *) &n, sizeof n);

 for(i=0; i<5; i++) // Отображаем значения, считанные из файла.

  cout << n[i] << " ";

 in.close();

 return 0;

}

Обратите внимание на то, что в инструкциях обращения к функциям read() и write() выполняются операции приведения типа, которые обязательны при использовании буфера, определенного не в виде символьного массива.

Функция gcount() возвращает количество символов, считанных при выполнении последней операции ввода данных.

Если конец файла будет достигнут до того, как будет считано num символов, функция read() просто прекратит выполнение, а буфер будет содержать столько символов, сколько удалось считать до этого момента. Точное количество считанных символов можно узнать с помощью еще одной функции-члена gcount(), которая имеет такой прототип.