under construction
Последний раз обновлено 27.06.01
Данный пример достаточно большой, чтобы увидеть отличия объектной модели от структурной и, с другой стороны, достаточно простой, чтобы не запутаться в его предметной области, любой знает, как он хочет просматривать файлы. Идея примера - просмотр файлов с запоминанием последнего состояния, см. раздел "Объектная модель". Предложенный в исходных текстах программы вариант создавался под консоль WIN32 в BC45.
К сожалению, мне не удалось создать простой класс преобразования в поток, что усложняет разбирательство с кодом, комментарии к некоторым методам, по техническим причинам, так же не отражают реального назначения точно, это придется установить просмотрев линию наследования.
Просмотр файла с памятью (проект VM)
Здесь я использую стандартные библиотеки и ряд своих определений. Все мои заголовки и библиотеки лежат в каталоге MYLIB. Каждая группа определений общего назначения находятся в каталоге PRJ\<имя группы>. После успешного создания .h и .lib файлов этих моих определений, те, которые необходимы, копируются в каталог MYLIB и являются библиотечными составляющими для остальной части программы.
Я хотел иметь последовательность разработки примера "с нуля", но по техническим причинам это сохранить не удалось. Есть только один из последних вариантов, который хотя и не реализует даже 50% от намеченного, но, я думаю, свою задачу примера ООП программы выполняет. Вот краткий перечень заголовков, библиотек, функций и классов. Чтобы узнать их лучше, надо просмотреть сами файлы.
conio.h
Просмотр файла с памятью (проект VM)
Это простые определения, которые позволяют сделать работу по заданию основных параметров и для улучшения независимости от ОС в вашей программе. Реально, получается целое семейство этих mydef.h
, для каждой ОС - свой файл. В этом файле есть несколько разделов.
Примитивные определения (mydef.h)
Как уже говорилось выше, для улучшения переноса программ на не flat модели, используется задание типов указателей на основные базовые с суффиксом _p, а так же удобное включение беззнаковости в целое с префиксом u_. В нужной модели вы правите только эту секцию. Это типы: u_int
, u_int_p
, int_p
etc.
Типы для сохранения я решил не использовать в примерах, но сразу скажу, что не текстовые файлы конфигурации записанные в 32 разрядных ОС могут не читаться на 16 разрядных ОС и наоборот. Это происходит не от того, что текстовый файл "универсальнее". Просто текстовый файл - одна из форм кодирования, общедоступная и, на мой взгляд, не лучшая для некоторых применений, иногда требуется для старых программ связи. Мы же не будем даже пальцем шевелить в этом направлении, так как есть чем еще заниматься. Вобщем, я написал по этому поводу больше слов, чем трудность проблемы.
Примитивные определения (mydef.h)
Для обработки ошибок будет использоваться подобный стандартному С приему assert()
. Но его заменим своими макросами, которые расширяют возможности по обработке и отображению ошибки. Надо сказать, что знатоки С++ сразу на меня ополчатся, сказав что ряд ошибок будут генерировать исключения ( неважно что это ) и наш макрос проверки не получит возможности выполняться. На что мы им ответим просто: раз эти генераторы такие умные, пусть сами свои исключения и ловят, а мы ничего генерировать не будем, и тем более ловить.
Тип ошибки задан как перечислимый тип t_err
. Глобальная переменная on_err
у нас всегда будет означать "останов по ошибке".
Строку описания ошибки можно получить с помощью
не спутайте со стандартной char_p strerr(t_err err);
strerror()
.
Используемые макросы
| вывести тип ошибки |
| ее же и сообщение |
| вывести сообщение и продолжить работу |
assert()
и вызывают системно-зависимую функцию вывода ошибки. Для WIN32 это
t_err errw32_(t_err error, char_p file, u_int line, char_p msg=0);
Система оповещения об ошибке в WIN32 вызовет модальное окно с кнопкой ОК.
Вот типичное использование фильтра ошибок. Я не люблю вставлять проверяемый код внутрь err()
, т.к. сообщений больше, чем просто "assertion failed".
|
При использовании такого способа оповещения об ошибке, не нужно всем функциям давать возврат t_err
. Но функция имеющая такой возврат может быть рестартована снаружи и ... Короче говоря, эти проблемы должны быть разрешимы силами программиста С.
Примитивные определения (mydef.h)
Прочитать строку из текстового файла в asciiz формат.
t_err getln(char_p buf, u_int max_len, FILE *fp);
Это работает для файлов, открытых как "rb". Признак конца строки \0x0A или EOF. Места в buf
должно быть не менее чем max_len+\0
(допускается сочетание getln(0,0)
- просто прочитать сроку и никуда не записать). Чтение останавливается после признака конца строки, запись после достижения max_len
, т.е. излишки строки более max_len
потеряются. Если в строке файла содержится символ \0, то он просто запишется и может вызвать ошибку определения длины прочитанной строки, если она не известна заранее. Символы \0x0D и \0x0A игнорируются не записываются в buf
и не подсчитываются для max_len
.
Такая функция удобна в тех файлах, где в первых позициях хранится нужная информация, а остальное надо пропустить до конца строки, для прокрутки строк и маркер конца строки записаный в текстовый файл как \r\n в DOS и как \n в UNIX работает правильно.
Просмотр файла с памятью (проект VM)