5.6. Блок управления файлом (FCB)

Прежде, чем перейти к упомянутому примеру, необходимо рассмотреть формируемую DOS структуру данных - блок управления файлом FCB (File Control Block), который является существенным элементом файловой системы и участвует во всех файловых операциях.

Блок управления файлом обеспечивает связь пользовательской программы с функциями DOS. При любой файловой операции происходит обращение к блоку FCB. На Фиг.5.5 показан состав стандартного блока FCB. Имеется модификация блока FCB, называемая расширенным блоком FCB, которая применяется в специальных случаях, когда нужно "скрыть" файл. Скрытый файл защищен от записи. Это значит, что программа не может модифицировать содержимое этого файла, не изменив предварительно его блока FCB. Скрытый файл не фигурирует в листинге справочника. Скрыть файл - один из простейших способов защиты файла от неумелого пользователя. В приводимых примерах используются только стандартные блоки FCB.

Поля данных блока FCB охватывают все атрибуты файла. Номер дисковода, имя и тип файла составляют идентификатор файла. Размер файла и дата яаляются атрибутами файла, которые приводятся в листинге справочника. Оставшиеся поля - текущий номер блока, длина записи и номер записи при произвольном доступе - служат для определения местоположения внутри файла при операциях чтения и записи. Длина записи указывает на число байтов в определяемой пользователем записи. Так как все операции чтения и записи в файл начинаются с границы записи, то длина записи определяет количество данных, обрабатываемых во время каждой из этих операций. Существуют два способа определения текущей записи при обращении к файлу. При первом, последовательном, способе записи обрабатываются по порядку. При этом текущий номер блока и относительный номер записи определяют запись, которая будет обрабатываться следующей. По мере того, как программа выполняет операции чтения или записи, DOS увеличивает на 1 относительный номер записи, чтобы он указывал на следующую запись. Выполнение

СмещениеОписание
0Номер носителя
1Имя файла
9Расширение
0CHТекущий блок
0EHРазмер записи
10HРазмер файла
14HДата
16HЗарезервировано
20HОтносительная запись (нумерация в блоке)
21HНомер записи прямого доступа

Фиг. 5.5 Блок управления файлом

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

Программа может обращаться к файлу, используя также и произвольный доступ. Произвольный в данном случае не означает, что запись выбирается случайным образом. Наоборот, это значит, что программа может выбрать в качестве следующей любую запись в файле. По-другому такой файл называют файлом с прямым доступом, так как у программы имеется непосредственный доступ к любой записи.

Программа может обращаться к файлу любым из двух указанных способов. При последовательных операциях DOS автоматически изменяет в блоке FCB значение поля относительного номера записи. При произвольном доступе к файлу номер записи должен определяться программой. В файловой системе файл с произвольным доступом является аналогом вектора. Точно так же, как для обращения к любому элементу вектора программа должна задать значение соответствующего индекса, так и при обращение к записи в файле с произвольным доступом номер записи должен определяться программой.

Теперь можно рассмотреть пример программы, использующей блок FCB и функции DOS. На Фиг. 5.6 приведена длинная программа, которая реально мало что делает. Ее цель - продемонстрировать использование блока FCB и функци DOS, связанных с прерыванием 21H. Однако содержащиеся в этой программе операции могут применяться в реальных задачах.


Microsoft (R) Macro Assembler Version 5.00                1/1/80 04:00:28
Фиг. 5.6 Пример использования функций ДОС                       Page  1-1
PAGE ,132

TITLE    Фиг. 5.6 Пример использования функций ДОС
0000                     CODE     SEGMENT
                         ASSUME   CS:CODE,DS:CODE
0000                     EXWORD   LABEL     WORD
0000                     EXBYTE   LABEL     BYTE
005C                              ORG       05CH        ; Положение первого поля FCB
005C                     FCB      LABEL     BYTE            ; Метка всего поля FCB
005C    ??               FCB_DRIVE          DB  ?           ; Номер устройства
005D    0008[            FCB_NAME           DB  8 DUP (?)   ; Имя файла
        ??
          ]
0065    0003[            FCB_EXT            DB  3 DUP (?)   ; Тип файла
        ??
          ]
0068    ????             FCB_BLOCK          DW  ?           ; Номер текущего блока
006A    ????             FCB_RECORD_SIZE    DW  ?           ; Размер записи
006C    ????????         FCB_FILE_SIZE      DD  ?           ; Размер файла
0070    ????             FCB_DATE           DW  ?           ; Дата последнего изменения
0072    000A[            FCB_RESV           DB  10 DUP (?)  ; Зарезервировано ДОС
        ??
          ]
007C    ??               FCB_CURRENT_RECORD DB  ?           ; Номер текущей записи
007D    ????????         FCB_RANDOM_RECORD  DD  ?           ; Номер записи при прямом
                                                            ; доступе
0090                              ORG       090H
0090                     DISK_TRANSFER_ADDRESS  LABEL BYTE  ; Буфер для данных
0100                              ORG       100H
                         ASSUME   CS:CODE,DS:CODE,ES:CODE
0100    E9 01CD R                 JMP       PROGRAM_START   ; Переход на начало программы
        = 0020           RECORD_SIZE        EQU       32    ; Размер записи
0103    03 00 00 00 00   KEYBOARD_BUFFER    DB        3, 0, 0, 0, 0  ; Буфер ввода с клавиатуры
0108    94 A0 A9 AB 20 E3 A6  FILE_ERROR_MSG    DB    'Файл уже существует', 10, 13, '$'
        A5 20 E1 E3 E9 A5 E1
        E2 A2 E3 A5 E2 0A 0D
        24
011E    8D A5 A2 AE A7 AC AE  BAD_OPEN_MSG      DB    'Невозможно открыть файл', 10, 13, '$'
        A6 AD AE 20 AE E2 AA
        E0 EB E2 EC 20 E4 A0
        A9 AB 0A 0D 24
0138    8E E8 A8 A1 AA A0 20  BAD_WRITE_MSG     DB    'Ошибка при записи в файл', 10, 13, '$'
        AF E0 A8 20 A7 A0 AF
        A8 E1 A8 20 A2 20 E4
        A0 A9 AB 0A 0D 24
0153    8E E8 A8 A1 AA A0 20  BAD_READ_MSG      DB     'Ошибка при чтении файла', 10, 13, '$'
        AF E0 A8 20 E7 E2 A5
        AD A8 A8 20 E4 A0 A9
        AB A0 0A 0D 24
016D    8E E8 A8 A1 AA A0 20  BAD_CLOSE_MSG     DB     'Ошибка при закрытии файла', 10, 13, '$'
        AF E0 A8 20 A7 A0 AA
        E0 EB E2 A8 A8 20 E4
        A0 A9 AB A0 0A 0D 24
0189    8F E0 A8 20 A2 A2 AE   INPUT_BAD_MSG     DB     'При вводе требуется два символа', 10, 13, '$'
        A4 A5 20 E2 E0 A5 A1
        E3 A5 E2 E1 EF 20 A4
        A2 A0 20 E1 A8 AC A2
        AE AB A0 0A 0D 24
01AB    82 A2 AE A4 20 A4 AE   CHAR_BAD_MSG      DB     'Ввод должен быть: символ|символ', 10, 13, '$'
        AB A6 A5 AD 20 A1 EB
        E2 EC 3A 20 E1 A8 AC
        A2 AE AB 7C E1 A8 AC
        A2 AE AB 0A 0D 24
                         ;-----   Установка буфера (Области связи с диском)
01CD                     PROGRAM_START:
01CD    B4 1A                     MOV       AH, 1AH       ; Установка буфера
01CF    8D 16 0090 R              LEA       DX, DISK_TRANSFER_ADDRESS
01D3    CD 21                     INT       21H
                         ;-----   Поиск файла
01D5    B4 11                     MOV       AH, 11H       ; Поиск файла с заданным
01D7    8D 16 005C R              LEA       DX, FCB       ; именем
01DB    CD 21                     INT       21H
01DD    0A C0                     OR        AL, AL
01DF    75 0A                     JNZ       NO_FILE       ; Переход если файл новый
01E1    8D 16 0108 R              LEA       DX, FILE_ERROR_MSG   ; Сообщение о неправильном
01E5                      ERROR_EXIT:                     ; имени файла
01E5    B4 09                     MOV       AH, 9H        ; Вывод сообщения на экран
01E7    CD 21                     INT       21H           ; и выход из программы
01E9    CD 20                     
                          ;-----  Создание нового файла
01EB                      NO_FILE:
01EB    B4 16                     MOV       AH, 16H       ; Создание файла
01ED    8D 16 005C R              LEA       DX, FCB
01F1    CD 21                     INT       21H
01F3    0A C0                     OR        AL, AL        ; Проверка на успех
01F5    74 06                     JZ        CREATE_OK
01F7    8D 16 011E R              LEA       DX, BAD_OPEN_MSG  ; Сообщение об ошибке при
01FB    EB E8                     JMP       ERROR_EXIT    ; создании файла
                          ;-----  Установка параметров FCB
01FD                      CREATE_OK:
01FD    C6 06 007C R 00           MOV       FCB_CURRENT_RECORD, 0  ; Инициализация номера
0202    C7 06 007D R 0000         MOV       WORD PTR FCB_RANDOM_RECORD, 0  ; записи
0208    C7 06 007F R 0000         MOV       WORD PTR FCB_RANDOM_RECORD+2, 0
020E    C7 06 006A R 0020         MOV       WORD PTR FCB_RECORD_SIZE, RECORD_SIZE
                          ;-----  Вывод в файл
0214    B0 41                     MOV       AL, 'A'       ; В этом цикле выводятся
0216                       CHARACTER_LOOP:
                          ; символы алфавита
0216    8D 3E 0090 R              LEA       DI, DISK_TRANSFER_ADDRESS
021A    B9 0020                   MOV       CX, RECORD_SIZE
021D    F3/ AA                    REP       STOSB         ; Заполнение буфера символами
021F    50                        PUSH      AX            ; Сохранение символа
0220    8D 16 005C R              LEA       DX, FCB
0224    B4 15                     MOV       AH, 15H       ; Последовательный вывод
0226    CD 21                     INT       21H           ; блока символов
0228    0A C0                     OR        AL, AL        ; Проверка на ошибку
022A    58                        POP       AX            ; Восстановление символа
022B    74 06                     JZ        WRITE_OK
022D    8D 16 0138 R              LEA       DX, BAD_WRITE_MSG  ; Ошибка записи
0231    EB B2                     JMP       ERROR_EXIT
0233                      WRITE_OK:
0233    FE C0                     INC       AL            ; Следующий символ
0235    3C 5B                     CMP       AL, 'Z'+1     ; Проверка на окончание вывода
0237    75 DD                     JNE       CHARACTER_LOOP  ; Вывод следующего символа
                          ;-----  Изменение файла
0239                      KEYBOARD_LOOP:                  ; Цикл ввода символов
0239    8D 16 0103 R              LEA       DX, KEYBOARD_BUFFER  ; с клавиатуры и
023D    B4 0A                     MOV       AH, 0AH       ; изменение файла
023F    CD 21                     INT       21H           ; Ввод с клавиатуры
0241    80 3E 0104 R 02           CMP       KEYBOARD_BUFFER+1, 2  ; Было введено два символа?
0246    74 0A                     JE        KEY_INPUT_OK
0248    8D 16 0189 R              LEA       DX, INPUT_BAD_MSG     ; Сообщение об ошибке
024C                      KEYBOARD_ERROR:
024C    B4 09                     MOV       AH, 9H
024E    CD 21                     INT       21H           ; Печать сообщения об ошибке
0250    EB E7                     JMP       KEYBOARD_LOOP ; Повторный ввод
0252                      KEY_INPUT_OK:
0252    8D 16 01AB R              LEA       DX, CHAR_BAD_MSG  ; Установка указателя на
                                                          ; сообщение об ошибке
0256    A0 0105 R                 MOV       AL, KEYBOARD_BUFFER+2  ; Выборка первого символа
0259    3C 24                     CMP       AL, '$'       ; Сравнение с символом конца
025B    75 03                     JNE       CHANGE_RECORD ; Изменение записи
025D    EB 5C 90                  JMP       PROGRAM_EXIT
                          ;-----  Чтение старой записи из файла
0260                      CHANGE_RECORD:
0260    3C 41                     CMP       AL, 'A'          ; Проверка на то, что символ
0262    7C E8                     JL        KEYBOARD_ERROR   ; находится в диапазоне A-Z
0264    3C 5A                     CMP       AL, 'Z'
0266    77 E4                     JA        KEYBOARD_ERROR
0268    2A E4                     SUB       AH, AH        ; Преобразование символа в
026A    2C 41                     SUB       AL, 'A'       ; номер записи
026C    A3 007D R                 MOV       word ptr FCB_RANDOM_RECORD, AX    
                                                          ; Занесение номера в FCB
026F    8D 16 005C R              LEA       DX, FCB
0273    B4 21                     MOV       AH, 21H       ; Прямое чтение записи
0275    CD 21                     INT       21H
0277    0A C0                     OR        AL, AL        ; Проверка на ошибку
0279    74 07                     JE        RANDOM_RECORD_OK
027B    8D 16 0153 R              LEA       DX, BAD_READ_MSG  ; Сообщение об ошибке
027F    E9 01E5 R                 JMP       ERROR_EXIT
                          ;-----  Вывод старой записи на экран
0282                      RANDOM_RECORD_OK:
0282    C6 06 00B0 R 0A           MOV       DISK_TRANSFER_ADDRESS+32, 10
                                                          ; Занесение символов конца
0287    C6 06 00B1 R 0D           MOV       DISK_TRANSFER_ADDRESS+33, 13
                                                          ; строки и конца вывода в буфер
028C    C6 06 00B2 R 24           MOV       DISK_TRANSFER_ADDRESS+34, '$'
0291    B4 09                     MOV       AH, 9H
0293    8D 16 0090 R              LEA       DX, DISK_TRANSFER_ADDRESS
0297    CD 21                     INT       21H           ; Вывод записи на экран
                          ;-----  Изменение файла
0299    A0 0106 R                 MOV       AL, KEYBOARD_BUFFER+3     
                                                          ; Выборка символа, на который будет
                                                          ; заменяться содержимое записи
029C    B9 001F                   MOV       CX, RECORD_SIZE-1
029F    8D 3E 0091 R              LEA       DI, DISK_TRANSFER_ADDRESS+1
02A3    F3/ AA                    REP       STOSB         ; Замена 31 символа
02A5    B4 22                     MOV       AH, 22H
02A7    8D 16 005C R              LEA       DX, FCB
02AB    CD 21                     INT       21H           ; Прямая запись на файла на
                                                          ; старое место
02AD    0A C0                     OR        AL, AL        ; Проверка на ошибку
02AF    74 07                     JZ        RANDOM_WRITE_OK
02B1    8D 16 0138 R              LEA       DX, BAD_WRITE_MSG  ; Сообщение об ошибке
02B5    E9 01E5 R                 JMP       ERROR_EXIT
02B8                      RANDOM_WRITE_OK:
02B8    E9 0239 R                 JMP       KEYBOARD_LOOP ; Обработка следующей записи
                          ;-----  Конец программы
02BB                      PROGRAM_EXIT:
02BB    B4 10                     MOV       AH, 10H       ; Закрытие файла
02BD    8D 16 005C R              LEA       DX, FCB
02C1    CD 21                     INT       21H
02C3    0A C0                     OR        AL, AL        ; Проверка на ошибку
02C5    74 07                     JZ        CLOSE_OK
02C7    8D 16 016D R              LEA       DX, BAD_CLOSE_MSG  ; Сообщение об ошибке
02CB    E9 01E5 R                 JMP       ERROR_EXIT
02CE                      CLOSE_OK:
02CE    CD 20                     INT       20H           ; Возврат в ДОС
02D0                      CODE    ENDS
                          END

                           Фиг. 5.6 Пример использования функциямй DOS (продолжение)

Приведенная программа состоит из двух частей. В первой части создается файл из 26 записей длиной по 32 байта. Каждая запись соответствует одной букве алфавита: запись 1 - это "AAAA...A", запись 2 - "BBBB...B" и т.д. Данный файл формируется последовательно. Во второй части программы этот файл рассматривается как файл с произвольным доступом. В ответ на введенный пользователем с клавиатуры запрос программа считывает и выводит на дисплей одну из 26 записей. С помощью этого же ввода осущкствляется редактирование записи: 31 символ записи, начиная со второго, заменяется на значение, которое вводится с клавиатуры. Выполнение программы завершается при вводе с клавиатуры символа "$".

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

Программа, приведенная на Фиг. 5.6, - это файл типа .COM. В следующем разделе мы обсудим различие между этим файлом и файлом типа .EXE. Использование в данном примере файла типа .COM позволяет для завершения работы программы воспользоваться прерыванием INT 20H. В случае файла типа .COM начало программы в сегменте должно иметь смещение 100H. Первые 100H байт программного сегмента называются программным префиксом PSP и предназначены для хранения некоторых специальных данных, которые используются программной, написанной на языке ассемблера.

Смещение блока FCB в сегменте равно 05CH, и использование в программе этого на первый взгляд произвольного адреса имеет определенные основания. Запись информации в данный блок FCB осуществляется командным процессором, входящим в состав DOS. После того, как пользователь вызвал программу, указав ее имя, DOS просматривает оставшуюся часть командной строки в поисках имен файлов. Первое встретившееся в команде имя помещается в блок FCB, смещение которого равно 05CH. Если в командной строке будет еще одно имя, то оно запишется в блок FCB со смещением 06CH. Так как в нашеи примере фигурирует только один файл, то используют только блок FCB со смещением 05CH. Запуск описываемой программы осуществляется с помощью следующей синтаксической конструкции:


A> FIG5=6 TEST.FIL

FIG5=6 - имя программы. В каталоге программа фигурирует под именем FIG5=6.COM. Файл TEST.FIL является файлом, который программа создает и затем модифицирует. Интерпретатор командных строк выбирает имя "TEST.FIL" и помещает его в соответствующее поле блока FCB со смещением 05CH. Рассматривая имя файла в качестве параметра командной строки, можно с помощью описываемой программы создавать и модифицировать любой файл. Если бы имя файла входило в ассемблерную программу, мы могли бы работать только с единственным файлом.

Начиная со смещения 05CH, текст программы соответствует структуре блока FCB. Первая ячейка идентифицируется меткой блока FCB. Каждое из полей FCB имеет свою метку и длину, так что программа может обрабатывать их непосредственно. Например, чтобы задать длину записи, программа модифицирует переменную FCB_RECORD_SIZE.

Начиная с адреса 080H помещается еще одно специальное поле программного префикса. Эта область памяти размером 128 байт отводится по умолчанию под область связи с диском DTA (Disk Transfer Area) и используется DOS в качестве буфера для всех файловых записей. Всякий раз, записывая или читая запись, DOS использует буфер области DTA. Во время инициализации DOS устанавливает смещение области DTA в программном сегменте равным 080H. Программа может изменить это значение, используя функцию 1AH прерывания 21H. Это смещение должно быть изменено, еслм длина записи больше, чем 128 байт. В рассматриваемом примере область связи с диском сдвигается до смещения в сегменте, равного 90H. Это связано с тем, что блок FCB со смещением 05CH выходит за границу с адресом 80H. Если бы граница области DTA определялась соглашением, принятым по умолчанию, то при передаче файлов информация в последнем байте блока FCB была бы разрушена. В этом байте записывается номер записи при произвольном доступе к файлу. Так как в данной программе для чтения-записи данных используется произвольный доступ, упомянутое наложение информации необходимо исключить.

Первая команда программы имеет смещение 100H и является переходом на фактическое начало программы. Такая структура программы может показаться неэффективной, однако ассемблирование происходит гораздо успешней, если все данные помещаются перед командами, которые на них ссылаются. Фактически в программе могут быть ошибки, если она содержит ссылки на данные вперед. Поэтому для большей надежности данные помещаются в начале программы.

В первой части программы устанавливается область связи с диском. В данной программе эта буферная область имеет смещение 90H. Так как длина записи равняется только 32 байтам, то впереди программы имется достаточно места.

Далее в программе используется прерывание 21H и функция DOS для поиска файла с именем, совпадающим с именем, записанным в блоке FCB. Обратите внимание, что пара регистров DC:DX указывает на блок FCB, как и должно быть при любых файловых операциях. Если система обнаружит файл с идентичным именем, программа завершит работу, выдав сообщение об ошибке и сохранив существующий уже файл. В данной программе обрабатываются только новые файлы. Существующие файлы здесь никак не используются, однако гарантируется, что их содержимое программой не сотрется. Конечно, в реальной практике програма была бы составлена так, чтобы охватывать случай как новых, так и уже существующих файлов.

Создание файла обеспечивается участком программы, помещенным NO_FILE. Формировать блок FCB до этого данной программе не нужно, так как он был сформирован командным процессором. Если описываемая файловая операция не сможет быть выполнена, например, из-за отсутствия свободного места на диске или отсутствия места в каталоге диска, то программа завершит выполнение и выдаст соответствующее сообщение об ошибке. При любом обращении DOS к файлу программа должна, прежде всего, открыть файл. Процедура открытия файла устанавливает связь между операционной системой и пользовательской программой. В процессе этой операции DOS просматривает справочник диска, находит нужный файл (или не находит, что соответствует сбойной ситуации) и заполняет поле блока FCB, относящееся к длине файла. После того, как файл открыт, DOS не должна просматривать справочник диска всякий раз, когда происходит обращение к файлу. Система DOS сохраняет в блоке FCB информацию о файле до тех пор, пока она этот файл не "закроет". Термины "закрыть" и "открыть" файл еще раз указывают на связь с традиционным делопроизводством. Папку с файлом документов нужно открыть прежде, чем можно будет ознакомиться содержащимся в ней бумагами, и закрыть до того, как ее уберут снова в бюро.

В рассматриваемом примере открытие файла происходит при его создании. Если бы такой файл уже существовал, связь с ним была бы установлена с помощью функции открытия файла (AH=0FH). Если открытие файла произошло успешно, программма изменяет значения некоторых полей блока FCB. В частности, длина записи должна быть установлена равной 32 байт, так как по умолчанию DOS считает ее равной 128 байт.

Часть программы с именем CHARACTER_LOOP передает в файл 26 записей. Определяющий символ каждой записи передается в буфер области DTA оператором REP STOSB. Отдельные записи передаются на диск с помощью функции последовательной записи (AH=0AH). Программа также выполняет проверку на отсутствие ошибок.

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

При вводе пользователем символа "$" программа заканчивает работу. В случае же ввода символов от "A" до "Z" программа осуществляет чтение соответствующей записи и выводит на дисплей ее содержимое. В оставшиеся 31 байт буфера программа записывает второй из введенных с клавиатуры символов. Модицифированная таким образом запись передается на диск в режиме произвольного доступа.

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

Приведенный на Фиг. 5.6 пример программы иллюстрирует основные способы обращения к файлу с помощью DOS. Эта программа ничего полезного не выполняет, однако приближение ее к реальным задачам потребовало бы намного большего числа команд, которые мало что прояснили бы в отношении использования функций DOS. В данной программе важно обратить внимание на необходимость проверки ошибок после каждой операции, выполняемой DOS. В то время, как DOS с помощью прерывания 24H обрабатывает аппаратные ошибки, пользовательская программа должна разрешать такие ситуации, как совпадение имен файлов или отсутствие свободного места на дискете. В данном примере обработка ошибок проста и состоит из вывода соответствующего сообщения и завершения работ программы. Обработка ошибок в реальных программах значительно сложнее и более актуальна, так как в этом случае возможность потери важной информации должна быть исключена.

И наконец, возможно, что проработав с данной программой, вы будете не очень удовлетворены ею как пользователь: в ней отсутствует запрос на ввод данных, сообщения об ошибках лаконичны и некоторые из выводимых сообщений частично накладываются на предыдущие, затирая их. Данная программа нуждается в доработке прежде, чем ею сможет воспользоваться кто-либо, не участвовавший в ее написании или тщательно в ней не разобравшийся.