Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции C++.doc
Скачиваний:
3
Добавлен:
01.05.2025
Размер:
1.44 Mб
Скачать

7.6.2 Чтение и запись в текстовые файлы

Для того чтобы писать в текстовые файлы или читать из них, достаточно воспользоваться опера­торами << и >> для открытого потока. Например, следующая программа записывает целое чис­ло, число с плавающей запятой и строку в файл 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();

Она возвращает число символов, прочитанных последним оператором двоичного ввода.