Двоичный режим ввода-вывода

Операций извлечения/передачи данных перегружены для всех встроенных типов и выполняют соответствующие преобразования из внутреннего представления данных в текстовое и из текстового во внутреннее (машинное). Однако в библиотеке C++ имеется немало функций бесформатного ввода-вывода, которые часто применяют для чтения и записи двоичных (не-текстовых) файлов.

Двоичный режим открытия файла (с установленным битом binary) означает, что никакой трансляции данных при передаче из файла в поток и обратно производиться не будет. Речь здесь идет не о форматных преобразованиях представления данных. При текстовом режиме (он принимается по умолчанию) при передаче данных между файлом и потоком производится замена пар символов CR/LF на единственный символ LF ('\n') и наоборот. Это происходит до преобразований представления, которые выполняются операциями извлечения/передачи. Двоичный ввод-вывод означает всего-навсего, что такой замены происходить не будет; тем не менее двоичный режим необходим при работе с сырыми данными, т. е. данными в машинной форме без преобразования их в текстовый формат.

Чтобы открыть файл в двоичном режиме, нужно, установить в параметре mode конструктора потока или функции open() бит ios::binary.

Чтение сырых данных производится функцией read() класса istream:

istream &read(char *buf, long len);

Здесь buf – адрес буфера, в который будут читаться данные, а len – число символов, которые нужно прочитать.

Запись сырых данных производится функцией write() класса ostream. Она выглядит точно так же, как функция read():

ostream &write(char *buf, long len);

Здесь buf – адрес буфера, в котором содержатся данные, а len – число символов, которые должны быть записаны в поток.

Обе функции возвращают ссылку на свой объект-поток. Это означает, что возможны их цепные вызовы, т. е. выражения вида:

ostream os(...);

os.write(...).write(...).write(...);

Чтение символов и строк

Для чтения одиночных символов, а также строк применяется функция get класса istream. Эта функция перегружена следующим образом:

int get();

istream &get(char &c) ;

istream &get(char *buf, long len, char t = '\n');

Две первые формы функции предназначены для извлечения из потока одиночного символа. Функция int get() возвращает символ в качестве своего значения. Функция get (char &c) передает символ в параметре и возвращает ссылку на свой поток.

Пример 11.1 Блок посимвольного копирования файлов

ifstream ifs("infile.dat");

ofstream ofs("outfile.dat");

// put (char) передает в поток

// одиночный символ.

while (ifs & ofs)

ofs.put(ifs.get());

Последняя форма функции get() извлекает из потока последовательность символов. Символы читаются в буфер buf, пока не произойдет одно из следующих событий:

- будет встречен ограничивающий символ t (по умолчанию '\n');

- будет встречен конец файла;

- в буфер будет записано len символов, включая завершающий строку 0.

Имеется еще функция getline(), во всем аналогичная этой форме get():

istream &getline(char *buf, long len, char t = '\n');

Разница между этими двумя функциями состоит в том, что getline() извлекает из потока ограничивающий символ, в то время как get() этого не делает. Ни та, ни другая функция не записывает ограничивающий символ в буфер.

Пример 11.2 Блок чтения строк с помощью get()

#include "stdafx.h"

#include <iostream>

using namespace std;

int main()

{

setlocale(LC_ALL, "Russian");

char name[9], ext[4];

cout << "Введите имя файла: ";

cin.get(name, 9, '.');

cin.ignore (80, '.'); // Удалить все оставшиеся до точки символы

cin.get(ext, 4) ;

cin.ignore(80, '\n'); // Удалить все, что осталось в строке

cout<< "Имя: "<< name << " Расширение: " << ext << endl;

return 0;

}

Наши рекомендации