ВІКІСТОРІНКА
Навигация:
Інформатика
Історія
Автоматизація
Адміністрування
Антропологія
Архітектура
Біологія
Будівництво
Бухгалтерія
Військова наука
Виробництво
Географія
Геологія
Господарство
Демографія
Екологія
Економіка
Електроніка
Енергетика
Журналістика
Кінематографія
Комп'ютеризація
Креслення
Кулінарія
Культура
Культура
Лінгвістика
Література
Лексикологія
Логіка
Маркетинг
Математика
Медицина
Менеджмент
Металургія
Метрологія
Мистецтво
Музика
Наукознавство
Освіта
Охорона Праці
Підприємництво
Педагогіка
Поліграфія
Право
Приладобудування
Програмування
Психологія
Радіозв'язок
Релігія
Риторика
Соціологія
Спорт
Стандартизація
Статистика
Технології
Торгівля
Транспорт
Фізіологія
Фізика
Філософія
Фінанси
Фармакологія


Определение пользовательских манипуляторов

 

Порядок создания пользовательского манипулятора с параметрами, например для вывода, следующий:

1. Определить класс (my_manip) с полями: параметры манипулятора, указатель на функцию типа

ostream& (*f)(ostream&,<параметры манипулятора>);

2. Определить конструктор этого класса (my_manip) с инициализацией полей.

3. Определить, в этом классе дружественную функцию – operator<<. Эта функция в качестве правого аргумента принимает объект класса my_manip, левого аргумента (операнда) поток ostream и возвращает поток ostream как результат выполнения функции *f. Например,

typedef far ostream&(far *PTF)(ostream&,int,int,char);

class my_man{

int w;int n;char fill;

PTF f;

public:

//конструктор

my_man(PTF F,int W,int N,char FILL):f(F),w(W),n(N),fill(FILL){}

friend ostream& operator<<(ostream&,my_man);

};

ostream& operator<<(ostream& out,my_man my)

{return my.f(out,my.w,my.n,my.fill);}

 

4. Определить функцию типа *f (fmanip), принимающую поток и параметры манипулятора и возвращающую поток. Эта функция собственно и выполняет форматирование. Например,

ostream& fmanip(ostream& s,int w,int n,char fill)

{s.width(w);

s.flags(ios::fixed);

s.precision(n);

s.fill(fill);

return s;}

5. Определить собственно манипулятор (wp) как функцию, принимающую параметры манипулятора и возвращающую объект my_manip, поле f которого содержит указатель на функцию fmanip. Например,

my_man wp(int w,int n,char fill)

{return my_man(fmanip,w,n,fill);}

Для создания пользовательских манипуляторов с параметрами можно использовать макросы, которые содержатся в файле <iomanip.h>:

OMANIP(int)

IMANIP(int)

IOMANIP(int)

 

Состояние потока.

Каждый поток имеет связанное с ним состояние. Состояния потока описываются в классе ios в виде перечисления enum.

public:

enum io_state{

goodbit, //нет ошибки 0Х00

eofbit, //конец файла 0Х01

failbit, //последняя операция не выполнилась 0Х02

badbit, //попытка использования недопустимой операции 0Х04

hardfail //фатальная ошибка 0Х08

};

Флаги, определяющие результат последней операции с объектом ios, содержатся в переменной state. Получить значение этой переменной можно с помощью функции int rdstate().

Кроме того, проверить состояние потока можно следующими функциями:

int bad(); 1, если badbit или hardfail

int eof(); 1, если eofbit

int fail(); 1, если failbit, badbit или hardfail

int good(); 1, если goodbit

 

 

Если операция >> используется для новых типов данных, то при её перегрузке необходимо предусмотреть соответствующие проверки.

Файловый ввод-вывод

 

Потоки для работы с файлами создаются как объекты следующих классов:

ofstream – запись в файл;

ifstream – чтение из файла;

fstream – чтение/запись.

Для создания потоков имеются следующие конструкторы:

fstream();

создает поток, не присоединяя его ни к какому файлу.

fstream(const char* name,int mode,int p=filebuf::openprot);

создает поток, присоединяет его к файлу с именем name, предварительно открыв файл, устанавливает для него режим mode и уровень защиты p. Если файл не существует, то он создается. Для mode=ios::out, если файл существует, то его размер будет усечен до нуля.

Флаги режима определены в классе ios и имеют следующие значения:

in - для чтения

out - для записи

ate - индекс потока помещен в конец файла. Чтение больше не допустимо, выводные данные записываются в конец файла;

app - поток открыт для добавления данных в конец. Независимо от seekp() данные будут записываться в конец;

trunc - усечение существующего потока до нуля;

nocreate -команда открытия потока будет завершена неудачно, если файл не существует;

noreplace -команда открытия потока будет завершена неудачно, если файл существует;

binary-поток открывается для двоичного обмена.

Если при создании потока он не присоединен к файлу, то присоединить существующий поток к файлу можно функцией

void open(const char* name,int mode,int p=filebuf::openprot);

Функция

void fstreambase::close();

сбрасывает буфер потока, отсоединяет поток от файла и закрывает файл. Эту функцию необходимо явно вызвать при изменении режима работы с потоком. Автоматически она вызывается только при завершении программы.

 

Таким образом, создать поток и связать его с файлом можно тремя способами:

1. Создается объект filebuf

filebuf fbuf;

Объект filebuf связывается с устройством (файлом)

fbuf.open(“имя”,ios::in);

Создается поток и связывается с filebuf

istream stream(&fbuf);

2. Создается объект fstream (ifstream, ofstream)

fstream stream;

Открывается файл, который связывается через filebuf с потоком

stream.open(“имя”,ios::in);

3. Создается объект fstream, одновременно открывается файл, который связывается с потоком

fstream stream(“имя”,ios::in);

 

Порядок выполнения работы.

 

1. Определить пользовательский тип данных (класс). Определить и реализовать в нем конструкторы, деструктор, операции присваивания, ввода и вывода для стандартных потоков.

2. Написать программу № 1 для создания объектов пользовательского класса (ввод исходной информации с клавиатуры с использованием перегруженной операции “>>“) и сохранения их в потоке (файле). Предусмотреть в программе вывод сообщения о количестве сохраненных объектов и о длине полученного файла в байтах.

3. Выполнить тестирование программы.

4. Реализовать для вывода в поток свой манипулятор с параметрами.

5. Написать программу № 2 для чтения объектов из потока, сохранения их в массиве и просмотра массива. Для просмотра объектов использовать перегруженную для cout операцию << и свой манипулятор. Предусмотреть в программе вывод сообщения о количестве прочитанных объектов и байтов.

6. Выполнить программу для чтения из файла сохраненных предыдущей программой объектов и их просмотра.

7. Написать программу № 3 для добавления объектов в поток.

8. Выполнить программу, добавив в поток несколько объектов и просмотреть полученный файл.

9. Написать программу № 4 для удаления объектов из файла.

10. Выполнить программу, удалив из потока несколько объектов и просмотреть полученный файл.

11. Написать программу № 5 для корректировки (т.е. замены) записей в файле.

12. Выполнить программу и просмотреть полученный файл.

 

Методические указания

 

1. В качестве пользовательского типа данных взять класс из лабораторной работы № 11. Поля класса типа char* заменить на char[целое].

2. В совокупности программы должны использовать все классы потоков: istream, ostream, fstream, ifstream, ofstream.

3. Также в программах следует показать все три способа создания потока и открытия файла (см. выше).

4. Необходимо продемонстрировать чтение из файла и запись в файл как с помощью функций read/write, так и с помощью перегруженных операций >>и <<.

5. Пользовательский манипулятор создается с не менее чем с двумя параметрами.

6. В качестве параметров манипулятора можно использовать:

а) ширину поля вывода;

б) точность вывода вещественных чисел;

в) символ-заполнитель;

г) способ выравнивания (к левой или правой границе)

и т.д.

7. В поток записать не менее 5 объектов.

8. После записи объектов в файл и перед чтением их из файла определить количество записанных объектов и вывести эту информацию.

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

а) стать на конец файла - функции seekp(),seekg();

б) определить размер файла в байтах - функции tellp(),tellg();

в) определить количество записанных объектов - размер файла поделить на размер объекта.

9. Поскольку в файле может храниться любое, заранее не известное, количество объектов, для их сохранения в программе № 2 при чтении из файла использовать динамический массив.

10. Следует определить функцию find(), которая принимает значение ключевого поля объекта и возвращает смещение этого объекта от начала файла. Вызывать эту функцию перед удалением/изменением объекта в файле.

11. Для изменения и удаления объекта написать функции del()иrepl(), которым передается ссылка на поток, смещение от начала файла изменяемой или удаляемой записи (результат вызова функции find), новое значение изменяемой записи.

 

Содержание отчета.

1. Титульный лист.

2. Постановка задачи.

3. Определение пользовательского класса.

4. Реализация манипулятора.

5. Реализация функций find(),del()и repl().

 

Контрольные вопросы.

1. Понятие потока;

2. Потоковые классы в С++;

3. Базовые потоки ввода-вывода4

4. Форматирование;

5. Манипуляторы;

6. Определение пользовательских манипуляторов;

7. Состояние потока;

8. Файловый ввод-вывод.


Самостоятельная работа № 3

”РЕШЕНИЕ УРАВНЕНИЙ И НЕРАВЕНСТВ С ИСПОЛЬЗОВАНИЕМ УСЛОВНОГО ОПЕРАТОРА”.

 

Цель :Получение навыков в выборе и использовании условных операторов Си++.

 

© 2013 wikipage.com.ua - Дякуємо за посилання на wikipage.com.ua | Контакти