Функции вывода put и write
Для вывода двоичных данных или отдельного символа можно использовать функцию-компонент put, объявленную в ostream следующим образом:
ostream ostream::put (char ch);
При объявлении int ch='x'; следующие две строки эквивалентны:
cout.put(ch);
cout << (char)ch;
Функция-компонент write позволяет вывод больших по размеру объектов:
ostream& ostream::write( signed char* ptr, int n);
ostream& ostream::write( unsigned char* ptr, int n);
Функции write выводят n символов (включая любые входящие пустые символы) в двоичном формате. В отличие от строковой вставки, write не прекращает работу, встретив пустой символ.
Например,
int x; char s[12];
cout.write((char *)&x, sizeof(x));
cout.write(s,sizeof(s));
пошлет не преобразованное представление х и s на стандартное устройство вывода.
Существует тонкое различие между форматированной операцией << и неформатированными функциями put и write. Форматированная операция может вызвать очистку связанных потоков и иметь атрибут ширины поля. Неформатированные операции не обладают этими свойствами. Поэтому cout << 'a' и cout put('a') могут давать разные результаты. Все флаги форматирования применимы к <<, но ни один из них не применим к put или write.
Пример: В файл, открытый в текстовом режиме, дважды записывается одна и та же строка: первый раз – посимвольно; второй – вся строка целиком.
#include <fstream.h>
#include <string.h>
#define n 40
main()
{ int i=0;
char str[n]="Записываемая строка\n";
ofstream fstr("ofstream.out");
while(str[i] !='\0')
{fstr.put(str[i]);
cout<<"\nПозиция маркера записи: "<<fstr.tellp();
i++;}
fstr.write(str,strlen(str));
cout<<"\nНовая позиция маркера записи: "<<fstr.tellp();
fstr.close();
}
Результат:
Позиция маркера записи: 1
Позиция маркера записи: 2
… … …
Позиция маркера записи: 19
Позиция маркера записи: 21
Новая позиция маркера записи: 42
При выводе данных в файл, открытый в текстовом режиме, автоматически выполняется преобразование \n = CR/LF, т.е. символ новой строки преобразуется в пару символов возврата каретки и перевода строки. При чтении происходит обратное преобразование. Именно поэтому наблюдается “скачок” счетчика: после 19 идет 21. Функция put(), записывающая в файл \n, на самом деле помещает в файл два других символа. Функция write() выполняет такое же преобразование, поэтому конечное число счетчика равно 42, а не 41.
Если в данной программе указать не текстовый, а двоичный файл
ofstream fstr("ofstream.out", ios::binary);
то такого “скачка” счетчика наблюдаться не будет, т.к. не происходит замены символа новой строки в пару символов возврата каретки и перевода строки.