ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 13.12.2020
Просмотров: 4226
Скачиваний: 28
Глава 40. Потоки ввода/вывода в C++
511
// закрываем выходной поток
out.close();
return 0;
}
40.6.5.2. Чтение бинарного файла
Пример чтения бинарного файла приведен в листинге 40.14.
Листинг 40.14. Чтение бинарного файла
#include <iostream>
#include <fstream>
using namespace std;
struct emp
{
int code;
char name[20];
double salary;
};
int main()
{
ifstream in; // входной поток
struct emp s; // для записей файла
long length, n; // длина файла, количество записей
// открываем входной поток в бинарном режиме
in.open("demo.bin");
if(!in.is_open())
{
cout << "Open file failed.\n";
return 0;
}
// определяем длину файла
in.seekg(0, ios::end);
length = in.tellg();
in.seekg(0, ios::beg);
Часть IV. Стандартная библиотека языка программирования С++
512
// подсчитываем количество записей
n = length / sizeof(emp);
// читаем записи
for (int i = 0; i < n; ++i)
{
in.read((char*)&s, sizeof(struct emp));
cout << "code: " << s.code << " name: " << s.name
<< " sal: " << s.salary << endl;
}
in.close();
return 0;
}
40.6.5.3. Модификация бинарного файла
Так как бинарные файлы содержат копии содержимого оператив-
ной памяти, то можно определить смещение нужной записи в би-
нарном файле, зная длину записей и длину файла. Отсюда следу-
ет, что при модификации бинарного файла нет необходимости
читать весь файл, читается, корректируется и записывается об-
ратно в файл только нужная запись. Поэтому бинарные файлы
также называются файлами прямого доступа.
Пример модификации бинарного файла приведен в листин-
ге 40.15.
Листинг 40.15. Модификация бинарного файла
#include <iostream>
#include <fstream>
using namespace std;
struct emp
{
int code;
char name[20];
double salary;
};
Глава 40. Потоки ввода/вывода в C++
513
int main()
{
fstream f; // поток для ввода/вывода
struct emp s; // для записей файла
unsigned i; // номер записи
// открываем поток в бинарном режиме
f.open("demo.bin", ios::binary|ios::in|ios::out);
if (!f.is_open())
{
cout << "Open file failed.\n";
return 0;
}
cout << "Input an index: "; // читаем индекс
cin >> i;
f.seekg(i * sizeof(struct emp)); // устанавливаем указатель
на нужную запись
f.read((char*)&s, sizeof(struct emp)); // читаем запись
из файла
if (!f.good())
{
cout << "Wrong index.\n";
f.close();
return 0;
}
cout << "code = " << s.code << " name = " << s.name
<< " sal = " << s.salary << endl;
f.close();
return 0;
}
40.6.6. Копирование файла
Пример копирования файлов приведен в листинге 40.16.
Часть IV. Стандартная библиотека языка программирования С++
514
Листинг 40.16. Копирование файла
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream in("test.txt");
ofstream out("new_test.txt");
if (!in.is_open())
{
cout << "Open file failed.\n";
return 0;
}
out << in.rdbuf(); // копируем файл
in.close();
out .close();
return 0;
}
40.7. Манипуляторы <iomanip>
Манипулятором потока
называется функция, которая изменяет
поток. Указатели на манипуляторы являются операндами пере-
груженных операторов вывода
<<
и ввода
>>
, которые определены
как члены шаблонов классов
basic_ostream<E, T>
и
basic_
istream<E, T>
соответственно.
Условно манипуляторы подразделяются на две группы: простые
манипуляторы и параметризованные манипуляторы. Далее рас-
смотрим эти группы манипуляторов подробнее.
40.7.1. Простые манипуляторы
Манипулятор потока, который не имеет параметров, называется
простым
. Или, если точнее,
простой манипулятор
имеет один
Глава 40. Потоки ввода/вывода в C++
515
параметр, который является ссылкой на поток, который он изме-
няет. Но т. к. манипулятор вызывается через указатель перегру-
женным оператором ввода или вывода, то этот параметр переда-
ется манипулятору неявно.
Обычно простые манипуляторы изменяют только состояние
управляющих флагов потока. Простые манипуляторы потоков,
которые определены в стандартной библиотеке ввода/вывода,
были рассмотрены в
разд. 40.2.4
,
40.3.2
и
40.4.2
.
Манипуляторы без параметров называются простыми потому,
что очень просто определить свой простой манипулятор потока.
Для этого не требуется перегружать операторы ввода и вывода.
Например, простой манипулятор, определенный в листинге 40.17,
выводит следующий после него текст с новой строки и выполня-
ет горизонтальную табуляцию.
Листинг 40.17. Пример простого манипулятора
#include <iostream>
using namespace std;
ostream& tabl(ostream& out)
{
out << '\n' << '\t';
return out;
}
int main()
{
cout << "This is an old string." << tabl
<< "This is a new string." << endl;
return 0;
}
40.7.2. Параметризованные манипуляторы
Манипулятор потока, который имеет параметры, называются
па-
раметризованным
. Далее перечислены параметризованные ма-
нипуляторы, которые объявлены в заголовочном файле iomanip: