Для того чтобы писать в текстовые файлы или читать из них, достаточно воспользоваться операторами << и >> для открытого потока. Например, следующая программа записывает целое число, число с плавающей запятой и строку в файл TEST:
#include <iostream.h>
#include <fstream.h>
int main()
{
ofstream out("test");
if(!out)
{
cout << "Cannot open file.\n";
return 1;
}
out << 10 << " " << 123.23 << "\n";
out << "This is a short text file.\n";
out.close();
return 0;
}
Следующая программа читает целое число, число с плавающей запятой, символ и строку из файла, созданного предыдущей программой:
#include <iostream.h>
#include <fstream.h>
int main()
{
char ch, str[80];
int i;
float f;
ifstream in("test");
if(!in)
{
cout << "Cannot open file.\n";
return 1;
}
in >> i;
in >> f;
in >> ch;
in >> str;
in.close();
cout << i << " " << f << " " << ch << "\n";
cout << str;
return 0;
}
При использовании оператора >> для чтения текстовых файлов надо иметь в виду, что происходит определенное преобразование символов. Например, символы-разделители опускаются. Если нужно предотвратить какое-либо преобразование символов, то необходимо использовать функции двоичного ввода/вывода C++, которые рассматриваются в следующем разделе.
7.6.3 Двоичный ввод/вывод
Имеется несколько способов для записи двоичных данных в файл и чтения из файла. В этой главе мы рассмотрим два из них. В первую очередь, можно записать байт с помощью функции-члена put() и прочитать байт, используя функцию-член get(). Функция get() имеет много форм, но наиболее употребительная версия показанная ниже, где приведена также функция put():
istream& get(char &ch);
ostream& put(char ch);
Функция get() читает единственный символ из ассоциированного потока и помещает его значение в ch. Она возвращает ссылку на поток. Функция put() пишет ch в поток и возвращает ссылку на этот поток.
ЗАМЕТКА: Работая с двоичными файлами, надо удостовериться, что они открыты с использованием спецификатора ios::binary.
Следующая программа выводит содержимое файла на экран. Она использует функцию get().
#include <iostream.h>
#include <fstream.h>
int main(int argc, char *argv[])
{
char ch;
if(argc != 2) return 1;
ifstream in(argv[1], ios::in | ios::binary);
if(!in)
{
cout << "Cannot open file.\n";
return 1;
}
while(in)
{
in.get(ch);
cout << ch;
}
in.сlоse();
return 0;
}
Когда in достигает конца файла, то принимает значение NULL, в результате чего цикл while заканчивается.
Имеется более компактная запись кода для этого цикла, как показано ниже:
while(in.get(ch)) cout << ch;
Такая запись работает, поскольку функция get() возвращает поток in, обращающийся в нуль, когда достигается конец файла.
Следующая программа использует функцию put() для записи строки, содержащей двоичные данные:
#include <iostream.h>
#include <fstream.h>
int main()
{
char *p = "hello there\n\r\xfe\xff";
ofstream out("test", ios::out | ios::binary);
if(!out) return 1;
while(*p) out.put(*p++);
out.close();
return 0;
}
Второй способ чтения и записи двоичных данных состоит в использовании функций read() и write(). Наиболее обычный способ использования этих функций соответствует прототипу:
istream& read(unsigned char *buf, int num);
ostream& write(const unsigned char *buf, int num);
Функция read() читает num байт из ассоциированного потока и посылает их в буфер buf. Функция write() пишет пит байт в ассоциированный поток из буфера buf. Следующая программа пишет и потом читает массив целых чисел:
#include <iostream.h>
#include <fstream.h>
int main()
{
int n[5] = {1, 2, 3, 4, 5};
ofstream out("test", ios::out | ios::binary);
if(!out) return 1;
out.write((unsigned char*)&n, sizeof(n));
out.close();
for(int i=0; i<5; i++) n[i] = 0;
ifstream in("test", ios::in | ios::binary);
in.read((unsigned char*)&n, sizeof(n));
for(i=0; i<5; i++) cout << n[i] << " ";
in.close();
return 0;
}
Следует обратить внимание, что приведение типов в вызовах read() и write() необходимо для работы с буфером, который не определен как массив символов.
Если конец файла достигается до того, как будет прочитано заданное число символов, функция read() просто прекращает работу и буфер содержит столько символов, сколько было прочитано. Можно определить, сколько символов было прочитано, используя другую функцию-член gcount(), имеющую следующий прототип:
int gcount();
Она возвращает число символов, прочитанных последним оператором двоичного ввода.