Ввод-вывод двоичных данных
Для ввода-вывода двоичных данных используются функции (методы классов ostream и istream) put, write и get, которые определены следующим образом:
ostream& ostream::put(char ch);//посылает ch в ostreamostream& ostream::write(const char* buff, int n);//посылает n символов из buff в ostream;Put и write позволяют выводить неформатированные двоичные данные в объект ostream. Put выводит один символ, а write может послать любое количество символов из указанного буфера. Write полезна, когда нужно вывести необработанные данные, которые могут включать нули. (Запись двоичных данных требует, чтобы файл был открыт в двоичном режиме.)
Обычное извлечение строки не будет работать до тех пор, пока строка не будет завершена нулем.
Входная версия put называется get:
char ch;cin.get(ch); //захватывает следующий символ из //cin независимо от того пробел это или нетДругая версия get позволяет захватывать любое количество необработанных, двоичных символов из istream до заданного максимума и помещать их в заданный буфер (так же, как и в случае с write, файлы должны быть открыты в двоичном режиме):
istream& istream::get(char *buff, int max, int term='\n');//читает символы до максимального количества из istream, а//затем помещает их в buff. Прекращает чтение, если//прочитан//символ, указанный в term.Можно установить term равным определенному конечному символу (по умолчанию — это символ новой строки), в котором get будет прекращать работу, если он будет достигнут прежде, чем max символов будет передано в buff.
Ввод/вывод с диска
Библиотека iostream включает много классов, порожденных из streambuf, ostream и istream, предоставляя, таким образом, широкий выбор методов ввода/вывода файлов. Класс filebuf например, поддерживает ввод/вывод через дескрипторы файлов с помощью функций элементов для открытия, закрытия и поиска.
Наиболее часто используемыми классами являются ifstream (порожденный из istream), ofstream (порожденный из ostream) и fstream (порожденный из iostream). Все они поддерживают форматированный файл ввода/вывода, используя объекты filebuf. Ниже приведен простой пример, который копирует существующий дисковый файл в другой заданный файл:
/* DCOPY исходный файл / файл назначения ** копирует существующий исходный файл в файл назначения ** Если последний существует, то он перезаписывается; ** если не существует, DCOPY создаст его, если это возможно **/#include <iostream.h>#include <process.h> // для exit()#include <fstream.h> // для ifstream, ofstreamint main(int argc, char* argv[]) { char ch; if (argc != 3) // проверка числа аргументов { cerr << "USAGE: dcopy file1 file2\n"; exit(-1); } ifstream source; // объявить входной и выходной потоки ofstream dest; source.open(argv[1],ios::nocreate); // должен быть исходный файл if (!source) { cerr << "Cannot open source file " << argv[1] << " for input\n"; exit(-1); } dest.open(argv[2]); // файл назначения будет создан, если // не он найден или создан/перезаписан, если найден if (!dest) { cerr << "Cannot open destination file " << argv[2] << " for output\n"; exit(-1); } while (dest && source.get(ch)) dest.put(ch); cout << "DCOPY completed\n"; source.close(); // закрыть оба потока dest.close();}Типичный вызов этой программы в командной строке выглядит следующим образом:
dcopy letter.spr letter.bak
Пример 2. Разработать программу для ввода/вывода с диска массива структур.
#include <iostream.h>#include <fstream.h> int main(int argc, char* argv[]){ struct emp { char* name; int dept; }; emp e[2]; e[0].name="aaaa"; e[0].dept=1; e[1].name="bbbbbbb"; e[1].dept=2; ifstream source; ofstream dest; char filename[20]="s.dat"; dest.open(filename); for(int i=0;i<2;i++) dest<<e[i].name<<" "<<e[i].dept<<endl; dest.close(); source.open(filename,ios::nocreate); // файл должен быть создан for(int i=0;i<2;i++) { source>>e[i].name>>e[i].dept; cout<<e[i].name<<" "<<e[i].dept<<endl; } source.close(); cin.get(); return 0;}При этом файл s.dat содержит следующие данные:
aaaa 1bbbbbbb 2Если поле name может содержать пробелы, то такой способ ввода/вывода непригоден. Нужно использовать разделитель полей, отличный от пробела, например, @.
for(int i=0;i<2;i++) dest<<e[i].name<<"@"<<e[i].dept<<endl;Теперь чтение данных будет выглядеть следующим образом:
char buf[22];for(int i=0;i<2;i++){ source.get(e[i].name, 100, '@'); source.get(); //отбросить @ source.get(buf, 100, '\n'); source.get(); //отбросить \n e[i].dept=atoi(buf); cout<<e[i].name<<" "<<e[i].dept<<endl;}Дата добавления: 2016-07-27; просмотров: 1559;