Zarechnev 16 / 16 / 15 Регистрация: 25.09.2011 Сообщений: 104 |
||||||||
1 |
||||||||
12.11.2011, 19:10. Показов 9986. Ответов 10 Метки 1, blockwrite, disk is full, disk write error, error 101, file, filemode, files, reset, rewrite, runtime error 101, school pak, write, writeln, доступ, запись, ошибка 101, ошибка записи на диск, переполнение диска, режим доступа, файл, файлы, Чтение (Все метки)
Здравствуйте, возникла проблема такого плана. Я понял, что ошибка кроется в процедуре add; в строке №93
Узнал, что эта ошибка появляется из-за «переполенния» файла. Своими силами больше не могу ничего сделать, поэтому пишу сюда. Надеюсь на вашу помощь. ИСХОДНИК:
Добавлено через 1 час 9 минут
0 |
Почетный модератор 64289 / 47588 / 32739 Регистрация: 18.05.2008 Сообщений: 115,181 |
|
12.11.2011, 21:54 |
2 |
У меня в Турбо Паскале все работает, в том числе и записывает без ошибок.
0 |
2857 / 1986 / 788 Регистрация: 23.09.2010 Сообщений: 4,877 |
|
12.11.2011, 21:57 |
3 |
Zarechnev, проверяли не в School Pak случайно?
0 |
16 / 16 / 15 Регистрация: 25.09.2011 Сообщений: 104 |
|
12.11.2011, 22:57 [ТС] |
4 |
да. через скул пак. через турбо все отлично? надо будет скачать, проверить. спасибо за информацию
0 |
2857 / 1986 / 788 Регистрация: 23.09.2010 Сообщений: 4,877 |
|
12.11.2011, 23:44 |
5 |
Zarechnev, тогда понятно.Это такой косяк. Смело эмулируйте в DosBox другой TP (можно скачать здесь на форуме).
0 |
16 / 16 / 15 Регистрация: 25.09.2011 Сообщений: 104 |
|
13.11.2011, 20:35 [ТС] |
6 |
Да, в Турбо все отлично работает. 1) Как удалить часть записи из файла не используя truncate? (в моем случае — запись о студенте) Если кому-то будет интересно и появится желание помочь, вот исходник с исполняемым файлом: Там у меня есть мелкие ошибки, которые никак не могу определить, а именно:
0 |
Puporev Почетный модератор 64289 / 47588 / 32739 Регистрация: 18.05.2008 Сообщений: 115,181 |
||||||||
13.11.2011, 21:33 |
7 |
|||||||
Как удалить часть записи Никак, только запись целиком, если последняя то
если не последняя, сдвиг всех элементов начиная с i+1 на 1 вверх, потом тоже самое. Добавлено через 2 минуты
Т.е. если файл не создан, вывод сообщения об ошибке. Знаю что используется IOResult,
или другой вариант, например выход из процедуры или программы.
0 |
16 / 16 / 15 Регистрация: 25.09.2011 Сообщений: 104 |
|
13.11.2011, 21:44 [ТС] |
8 |
Так, с этим понял, спасибо, а насчет мелких непонятных ошибок можете подсказать? Добавлено через 7 минут
0 |
Почетный модератор 64289 / 47588 / 32739 Регистрация: 18.05.2008 Сообщений: 115,181 |
|
14.11.2011, 07:43 |
9 |
Конкретно что читать я не знаю, основы описаны практически везде, а навыки приобретал методом проб и ошибок.
1 |
Mawrat 13095 / 5876 / 1706 Регистрация: 19.09.2009 Сообщений: 8,808 |
||||||||
27.05.2013, 10:38 |
10 |
|||||||
Здравствуйте, возникла проблема такого плана. В некоторых сборках School Pak при попытке выполнить запись в файл, например, с помощью Write(), Writeln(), BlockWrite(), возникает ошибка времени выполнения: «Ошибка 101: Ошибка записи на диск» (Error 101: Disk write error) Это происходит из-за того, что в сборке School Pak по умолчанию может быть задан режим доступа к файлам с разрешением только на чтение. Режим доступа устанавливается через системную переменную FileMode (модуль System): FileMode = 0 — только чтение. По умолчанию в Borland/Turbo Pascal установлено: FileMode = 2, а в School Pak может быть: FileMode = 0 — только чтение.
—
2 |
Puporev |
27.05.2013, 10:50
|
Не по теме: Правда теме 2 года…
0 |
Ошибки ввода-вывода
100
Disk read error (Ошибка чтения диска)
Ошибка
генерируется процедурой Read при попытке
осуществить считывание после конца
типизированного файла.
101
Disk write error (Ошибка записи на диск)
Ошибка генерируется
процедурами Close, Write, WriteLn, Flush, если на
диске нет свободного места.
102
File not assigned (Файл
не
связан)
Ошибка
генерируется процедурами Reset, Rewrite,
Append, Rename и Erase, если с файловой переменной
не было связано имя физического файла
посредством обращения к процедуре
Assing.
103
File not open (Файл
не
открыт)
Ошибка
генерируется
процедурами
Close, Read, Write, Seek, Eof, FilePos, FileSIze, Flush, BlockRead
или
BlockWrite при
попытке
осуществить
операции
ввода-вывода
с
файлом,
который
еще
не
открыт.
104
File not open for Input (Файл
не
открыт
для
ввода)
Ошибка генерируется
процедурами Read, ReadLn, Eof, Eoln, SeekEof или
SeekEoln, если текстовый файл не открыт для
чтения.
105
File not open for output (Файл не открыт для вывода)
Ошибка
генерируется процедурами Write, WriteLn, если
текстовый файл не открыт для записи.
106
Invalid numeric format (Недопустимый числовой
формат)
Ошибка
генерируется процедурами Read или ReadLn,
если числовое значение, считанное из
текстового файла, не соответствует
числовому формату соответствующего
типа данных.
Критические ошибки
150
Disk is write-protected (Диск защищен от записи)
151
Bad drive request structure length (Неправильная длина
структуры запроса дисковода)
152
Drive not ready (Дисковод не готов)
153
Unknown command (Неизвестная команда)
154
CRC error In data (Ошибка контроля данных)
155
Bad drive request structure length (При обращении к
диску указана неверная длина структуры)
156
Disk seek error (Ошибка при поиске дорожки
диска)
157
Unknown media type (Неизвестный тип носителя)
158
Sector not found (Сектор
не
найден)
159
Printer out of paper (Принтер
без
бумаги)
160
Device write fault (Неисправное устройство
записи)
161
Device read fault (Неисправное устройство
чтения)
162
Hardware
failure (Сбой аппаратных средств).
Приложение №2
НАЗНАЧЕНИЕ
ФУНКЦИОНАЛЬНЫХ КЛАВИШ
Горячая клавиша |
Эквивалентная команда |
Функция |
[F1] |
Активизация |
|
[Alt+F1] |
Возврат к |
|
[Ctrl+F1] |
Активизация |
|
[Shift+F1] |
Help/Index |
Вызов содержания |
[F2] |
[F1] |
— |
[Ctr+F2] |
[Alt+F1] |
Help/Previous topic |
[F3] |
[Ctrl+F1] |
Help/Topic search |
[Alt+F3] |
Window /Close |
Закрытие активного |
[Ctrl+F3] |
Debug/Call Stack |
Открытие |
[F4] |
Run/ Goto Cursor |
Выполнение |
[Ctrl+F4] |
Dеbug/Evaluate/Modify |
Присмотр и |
[F5] |
Window/Zoom |
Изменение |
[Alt+F5] |
Debug/User Screen |
Переключение |
[Ctrl+F5] |
Window/Size/ Move |
Изменение |
[F6] |
Window/Next |
Переход к |
[Snift+F6] |
Window/Pfevious |
Возврат к |
[F7] |
Run/Trace Into |
Трассировка |
[Alt+F7] |
Tools/Goto |
Переход |
[Ctrl+F7] |
Debug/Add watch |
Дополнение |
[F8] |
Run/Step over |
Трассировка |
[Alt+F8] |
Tools/Go to next |
Переход |
[Ctrl+F8] |
Установка |
|
[F9] |
Compile/ Make |
Компиляция |
[Alt+F9] |
Compile/ Compile |
Компиляция |
[Ctrl+F9] |
Run/Run |
Компиляция |
[F10] |
— |
Активизация |
[Alt+F10] |
— |
Вызов локального |
[Alt+Литера] |
Открытие |
|
[Alt+Backsp] |
Edit/Undo |
Отмена всех |
[Alt+X] |
File/Exit |
Завершение |
[Alt+Цифра] |
— |
Переход к окну |
[Alt+0] |
Window/List |
Вызов |
[Ctrl+Del] |
Edit/Clear |
Удаление |
[Ctrl+Ins] |
Edit/Copy |
Копирование |
[Shift+Del] |
Edit/Cut |
Перенос |
[Shift+Ins] |
Edit/Paste |
Копирование |
Приложение №3
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
- #
- #
- #
- #
- #
- #
- #
- #
- #
- #
- #
Приложения написанные на Free Pascal могут генерировать ошибку времени выполнения (Run Time Error) когда в программе обнаруживаются определённые аварийные состояния . Этот документ содержит список возможных ошибок и описание их возможных причин.
1 Invalid function number (Неправильный номер функции)
Была попытка неправильного вызова системной функции.
2 File not found (Файл не найден)
Генерируется при попытке перенаименования, стирания или открытия несуществующего файла.
3 Path not found (Путь(директория) не найден)
Генерируется файловой системой когда путь не существует или неправелен.
Также генерируется при попытке получить доступ к несуществующему файлу.
4 Too many open files (Слишком много файлов открыто)
Максимальное число открытых файлов для вашего процесса было превышено.
Большинство операционных систем ограничивают максимальное число открытых файлов,
и эта ошибка может возникнуть когда этот лимит превышен.
5 File access denied (В доступе к файлу — отказано)
Было запрешено получение доступа к файлу. Эта ошибка может произойти по нескольким причинам:
-
При попытке открыть файл, предназначенный только для чтения или в деиствительности являющиёся директорией, для записи.
-
В данный момент занят или заблокирован другим процессом.
-
При попытке создания файла или директории с именем, которое совпадает с именем уже созданного файла или директории.
-
При попытке чтения из файла, открытого только для записи.
-
При попытке записи в файл, открытый только для чтения.
-
При попытке удалить директорию или файл, когда это не возможно.
-
При неимении прав на доступ к данному файлу.
6 Invalid file handle (Неправильный хэндл файла)
Происходит, когда используемая Вами файловая переменная была обнулена (испорчена); Это говорит о том, что память вашей программы была повреждена.
12 Invalid file access code (Неправильные ключи доступа к файлу)
Генерируется когда процедуры reset или rewrite вызываются с неправильным параметром FileMode.
15 Invalid drive number (Неправильный номер диска)
Генерируется когда в функции Getdir или ChDir был передан неправильный номер диска.
16 Cannot remove current directory (Невозможно удалить текущую директорию)
Генерируется при попытке удалить текущую директорию.
17 Cannot rename across drives (Можно переименовывать файлы только в пределах одного диска)
Вы не можете переименовать файл в файл, находяшиёся на другом диске или в другом разделе.
100 Disk read error (Ошибка чтения с диска)
Генерируется при невозможности произвести чтение с диска. Обычно происходит при попытке чтения данных, после его окончания.
101 Disk write error (Ошибка записи на диск)
Генерируется когда Вы пытаетесь записать данные на переполненый диск.
102 File not assigned (Файл не определён)
Генерируется функциями Reset, Rewrite, Append, Rename и Erase, При передаче в них файловой переменной, для которой не была выполнена функция AssignFile.
103 File not open (Файл не открыт)
Генерируется следующими функциями : Close, Read, Write, Seek, EOf, FilePos, FileSize, Flush, BlockRead, и BlockWrite если файл не был открыт.
104 File not open for input (Файл не открыт для чтения)
Генерируется функциями Read, BlockRead, Eof, Eoln, SeekEof и SeekEoln если файл не был открыт при помощи Reset.
105 File not open for output (Файл не открыт для записи)
Генерируется функцией write если текстовый файл не был открыт при помощи Rewrite.
106 Invalid numeric format(Неправильный числовой формат)
Генерируется когда ожидалось числовое значение, но из текстого файла было прочитано не было.
150 Disk is write-protected (Диск защищён от записи)
(Критическая ошибка)
151 Bad drive request struct length (Неправильная длина структуры запроса)
(Критическая ошибка)
152 Drive not ready (Устройство не готово)
(Критическая ошибка)
154 CRC error in data (Ошибка контрольной суммы в данных)
(Критическая ошибка)
156 Disk seek error (Ошибка низкоуровнего поиска на диске)
(Критическая ошибка)
157 Unknown media type (Неизвестный тип …)
(Критическая ошибка)
158 Sector Not Found (Сектор не найден)
(Критическая ошибка)
159 Printer out of paper (Нет бумаги в принтере)
(Критическая ошибка)
160 Device write fault (Сбой записи устройства)
(Критическая ошибка)
161 Device read fault (Сбой чтения устройства)
(Критическая ошибка)
162 Hardware failure (Сбой железа)
(Критическая ошибка)
200 Division by zero (Деление на ноль)
Приложение пыталось разделить число на ноль.
201 Range check error (Ошибка проверки границ)
Если вы компилировали прогамму с включённой провереой границ, Вы можете получить эту ошибку в следующих случаях:
-
Массив был вызван с индексом, выходящим за декларированые пределы.
-
Попытка присвоить значение переменной, выходящее за декларированые границы (для instance и enumerated типов).
202 Stack overflow error (Переполнение стека)
Стек превысил свой максимально допустимый размер (в этом случае необходимо уменьшить размер локальных переменных), или стек был повреждён. Эта ошибка генерируется только с включённой проверкой стека.
203 Heap overflow error (Переполнение кучи)
Размер кучи превысил максимально возможный размер. Генерируется при попытке выделить память непосредственно функциями New, GetMem и ReallocMem, или когда экземпляр класса или объекта создаётся и памяти не достаточно. Пожалуйста учтите что, по умолчанию, Free Pascal поддерживает увеличение кучи, то есть, если необходимо, будет произведена попытка её увеличения. Как бы то ни было, если размер кучи превысил максимально допустимый системой и
железом, то Вы получите эту ошибку.
204 Invalid pointer operation (Непрваильная операция с указателем)
Будет сгенерирована при вызове функций Dispose или Freemem с неправильным указателем (чаще всего, Nil)
205 Floating point overflow (Максимальная границы числа с плавающей точкой)
Вы попытались использовать или создать слишком большое число с плавающей точкой.
206 Floating point underflow (Минимальная граница числа с плавающей точкой)
Вы попытались использовать или создать слишком маленькое число с плавающей точкой.
207 Invalid floating point operation (Неправильная операция над числами с плавающей точкой)
Может генерироваться если вы попытались получить квадратный корень или логарифм отрицательного числа.
210 Object not initialized (Объект не инициализирован)
Если программа была скомпилирована с включенной проверкой границ, эта ошибка будет сгенерирована при попытке вызвать виртуальный метод до его конструктора.
211 Call to abstract method (Попытка вызова абстрактного метода)
Ваша программа попыталась вызвать абстрактный виртуальный метод. Абстрактные методы должны быть перекрыты, и только перекрытый метод должен быть вызван.
212 Stream registration error (Ошибка регистрации потока)
Генерируется когда неправильный тип регистрируется в модуле objects.
213 Collection index out of range (Индекс элемента коллекции выходит за допустимые границы)
Генерируется когда Вы попытались обратиться к элементу коллекции с выходящим за допустимые границы индексом (модуль objects).
214 Collection overflow error (Переполнение коллекции)
Размер коллекции превысил максимально допустимый размер, а Вы попытались добавить новый элемент (модуль objects).
215 Arithmetic overflow error (Арифметическое переполнение)
Эта ошибка генерируется когда результат операции превысил допустимые границы. В отличие to Turbo Pascal, эта ошибка генерируется только для 32-bit и 64-bit арифметических переполнений. Это происходит согласно тому, что все операнды конвертируются в 32-bit или 64-bit, до того как производить вычисления.
216 General Protection fault (GP Ошибка защиты памяти)
Приложение попыталось обратиться к недопустимому участку памяти. Это может быть вызвано следующими причинами:
-
Попытка получить разуказатель для nil.
-
Попытка получить доступ к выходящему за допустимые границы участку памяти (например, вызов move с неправильной длиной).
217 Unhandled exception occurred (Произошо неизвестное исключение)
Произошло исключение, и для него не существеет хэндла. Модуль sysutils устанавливает handler(менеджер), который отлавливает все исключения, и безопасно выходит в случае обнаружения оного.
219 Invalid typecast (Неправильное приведение типов)
Генерируется когда недопустимое приведение типов производится над классом используя оператор as. Эта ошибка также генерируется, когда объект или класс приводится к недопустимому объекту или классу, и виртуальный метод этого объекта или класса вызывается. Эта последняя ошибка детектируется только с использованием опции -CR компилятора.
227 Assertion failed error (Сбой утверждения)
Утверждение провалено, и процедурная переменная AssertErrorProc не была уcтановлена.
Приложения написанные на Free Pascal могут генерировать ошибку времени выполнения (Run Time Error) когда в программе обнаруживаются определённые аварийные состояния . Этот документ содержит список возможных ошибок и описание их возможных причин.
1 Invalid function number (Неправильный номер функции)
Была попытка неправильного вызова системной функции.
2 File not found (Файл не найден)
Генерируется при попытке перенаименования, стирания или открытия несуществующего файла.
3 Path not found (Путь(директория) не найден)
Генерируется файловой системой когда путь не существует или неправелен.
Также генерируется при попытке получить доступ к несуществующему файлу.
4 Too many open files (Слишком много файлов открыто)
Максимальное число открытых файлов для вашего процесса было превышено.
Большинство операционных систем ограничивают максимальное число открытых файлов,
и эта ошибка может возникнуть когда этот лимит превышен.
5 File access denied (В доступе к файлу — отказано)
Было запрешено получение доступа к файлу. Эта ошибка может произойти по нескольким причинам:
-
При попытке открыть файл, предназначенный только для чтения или в деиствительности являющиёся директорией, для записи.
-
В данный момент занят или заблокирован другим процессом.
-
При попытке создания файла или директории с именем, которое совпадает с именем уже созданного файла или директории.
-
При попытке чтения из файла, открытого только для записи.
-
При попытке записи в файл, открытый только для чтения.
-
При попытке удалить директорию или файл, когда это не возможно.
-
При неимении прав на доступ к данному файлу.
6 Invalid file handle (Неправильный хэндл файла)
Происходит, когда используемая Вами файловая переменная была обнулена (испорчена); Это говорит о том, что память вашей программы была повреждена.
12 Invalid file access code (Неправильные ключи доступа к файлу)
Генерируется когда процедуры reset или rewrite вызываются с неправильным параметром FileMode.
15 Invalid drive number (Неправильный номер диска)
Генерируется когда в функции Getdir или ChDir был передан неправильный номер диска.
16 Cannot remove current directory (Невозможно удалить текущую директорию)
Генерируется при попытке удалить текущую директорию.
17 Cannot rename across drives (Можно переименовывать файлы только в пределах одного диска)
Вы не можете переименовать файл в файл, находяшиёся на другом диске или в другом разделе.
100 Disk read error (Ошибка чтения с диска)
Генерируется при невозможности произвести чтение с диска. Обычно происходит при попытке чтения данных, после его окончания.
101 Disk write error (Ошибка записи на диск)
Генерируется когда Вы пытаетесь записать данные на переполненый диск.
102 File not assigned (Файл не определён)
Генерируется функциями Reset, Rewrite, Append, Rename и Erase, При передаче в них файловой переменной, для которой не была выполнена функция AssignFile.
103 File not open (Файл не открыт)
Генерируется следующими функциями : Close, Read, Write, Seek, EOf, FilePos, FileSize, Flush, BlockRead, и BlockWrite если файл не был открыт.
104 File not open for input (Файл не открыт для чтения)
Генерируется функциями Read, BlockRead, Eof, Eoln, SeekEof и SeekEoln если файл не был открыт при помощи Reset.
105 File not open for output (Файл не открыт для записи)
Генерируется функцией write если текстовый файл не был открыт при помощи Rewrite.
106 Invalid numeric format(Неправильный числовой формат)
Генерируется когда ожидалось числовое значение, но из текстого файла было прочитано не было.
150 Disk is write-protected (Диск защищён от записи)
(Критическая ошибка)
151 Bad drive request struct length (Неправильная длина структуры запроса)
(Критическая ошибка)
152 Drive not ready (Устройство не готово)
(Критическая ошибка)
154 CRC error in data (Ошибка контрольной суммы в данных)
(Критическая ошибка)
156 Disk seek error (Ошибка низкоуровнего поиска на диске)
(Критическая ошибка)
157 Unknown media type (Неизвестный тип …)
(Критическая ошибка)
158 Sector Not Found (Сектор не найден)
(Критическая ошибка)
159 Printer out of paper (Нет бумаги в принтере)
(Критическая ошибка)
160 Device write fault (Сбой записи устройства)
(Критическая ошибка)
161 Device read fault (Сбой чтения устройства)
(Критическая ошибка)
162 Hardware failure (Сбой железа)
(Критическая ошибка)
200 Division by zero (Деление на ноль)
Приложение пыталось разделить число на ноль.
201 Range check error (Ошибка проверки границ)
Если вы компилировали прогамму с включённой провереой границ, Вы можете получить эту ошибку в следующих случаях:
-
Массив был вызван с индексом, выходящим за декларированые пределы.
-
Попытка присвоить значение переменной, выходящее за декларированые границы (для instance и enumerated типов).
202 Stack overflow error (Переполнение стека)
Стек превысил свой максимально допустимый размер (в этом случае необходимо уменьшить размер локальных переменных), или стек был повреждён. Эта ошибка генерируется только с включённой проверкой стека.
203 Heap overflow error (Переполнение кучи)
Размер кучи превысил максимально возможный размер. Генерируется при попытке выделить память непосредственно функциями New, GetMem и ReallocMem, или когда экземпляр класса или объекта создаётся и памяти не достаточно. Пожалуйста учтите что, по умолчанию, Free Pascal поддерживает увеличение кучи, то есть, если необходимо, будет произведена попытка её увеличения. Как бы то ни было, если размер кучи превысил максимально допустимый системой и
железом, то Вы получите эту ошибку.
204 Invalid pointer operation (Непрваильная операция с указателем)
Будет сгенерирована при вызове функций Dispose или Freemem с неправильным указателем (чаще всего, Nil)
205 Floating point overflow (Максимальная границы числа с плавающей точкой)
Вы попытались использовать или создать слишком большое число с плавающей точкой.
206 Floating point underflow (Минимальная граница числа с плавающей точкой)
Вы попытались использовать или создать слишком маленькое число с плавающей точкой.
207 Invalid floating point operation (Неправильная операция над числами с плавающей точкой)
Может генерироваться если вы попытались получить квадратный корень или логарифм отрицательного числа.
210 Object not initialized (Объект не инициализирован)
Если программа была скомпилирована с включенной проверкой границ, эта ошибка будет сгенерирована при попытке вызвать виртуальный метод до его конструктора.
211 Call to abstract method (Попытка вызова абстрактного метода)
Ваша программа попыталась вызвать абстрактный виртуальный метод. Абстрактные методы должны быть перекрыты, и только перекрытый метод должен быть вызван.
212 Stream registration error (Ошибка регистрации потока)
Генерируется когда неправильный тип регистрируется в модуле objects.
213 Collection index out of range (Индекс элемента коллекции выходит за допустимые границы)
Генерируется когда Вы попытались обратиться к элементу коллекции с выходящим за допустимые границы индексом (модуль objects).
214 Collection overflow error (Переполнение коллекции)
Размер коллекции превысил максимально допустимый размер, а Вы попытались добавить новый элемент (модуль objects).
215 Arithmetic overflow error (Арифметическое переполнение)
Эта ошибка генерируется когда результат операции превысил допустимые границы. В отличие to Turbo Pascal, эта ошибка генерируется только для 32-bit и 64-bit арифметических переполнений. Это происходит согласно тому, что все операнды конвертируются в 32-bit или 64-bit, до того как производить вычисления.
216 General Protection fault (GP Ошибка защиты памяти)
Приложение попыталось обратиться к недопустимому участку памяти. Это может быть вызвано следующими причинами:
-
Попытка получить разуказатель для nil.
-
Попытка получить доступ к выходящему за допустимые границы участку памяти (например, вызов move с неправильной длиной).
217 Unhandled exception occurred (Произошо неизвестное исключение)
Произошло исключение, и для него не существеет хэндла. Модуль sysutils устанавливает handler(менеджер), который отлавливает все исключения, и безопасно выходит в случае обнаружения оного.
219 Invalid typecast (Неправильное приведение типов)
Генерируется когда недопустимое приведение типов производится над классом используя оператор as. Эта ошибка также генерируется, когда объект или класс приводится к недопустимому объекту или классу, и виртуальный метод этого объекта или класса вызывается. Эта последняя ошибка детектируется только с использованием опции -CR компилятора.
227 Assertion failed error (Сбой утверждения)
Утверждение провалено, и процедурная переменная AssertErrorProc не была уcтановлена.
Приложения написанные на Free Pascal могут генерировать ошибку времени выполнения (Run Time Error) когда в программе обнаруживаются определённые аварийные состояния . Этот документ содержит список возможных ошибок и описание их возможных причин.
1 Invalid function number (Неправильный номер функции)
Была попытка неправильного вызова системной функции.
2 File not found (Файл не найден)
Генерируется при попытке перенаименования, стирания или открытия несуществующего файла.
3 Path not found (Путь(директория) не найден)
Генерируется файловой системой когда путь не существует или неправелен.
Также генерируется при попытке получить доступ к несуществующему файлу.
4 Too many open files (Слишком много файлов открыто)
Максимальное число открытых файлов для вашего процесса было превышено.
Большинство операционных систем ограничивают максимальное число открытых файлов,
и эта ошибка может возникнуть когда этот лимит превышен.
5 File access denied (В доступе к файлу — отказано)
Было запрешено получение доступа к файлу. Эта ошибка может произойти по нескольким причинам:
-
При попытке открыть файл, предназначенный только для чтения или в деиствительности являющиёся директорией, для записи.
-
В данный момент занят или заблокирован другим процессом.
-
При попытке создания файла или директории с именем, которое совпадает с именем уже созданного файла или директории.
-
При попытке чтения из файла, открытого только для записи.
-
При попытке записи в файл, открытый только для чтения.
-
При попытке удалить директорию или файл, когда это не возможно.
-
При неимении прав на доступ к данному файлу.
6 Invalid file handle (Неправильный хэндл файла)
Происходит, когда используемая Вами файловая переменная была обнулена (испорчена); Это говорит о том, что память вашей программы была повреждена.
12 Invalid file access code (Неправильные ключи доступа к файлу)
Генерируется когда процедуры reset или rewrite вызываются с неправильным параметром FileMode.
15 Invalid drive number (Неправильный номер диска)
Генерируется когда в функции Getdir или ChDir был передан неправильный номер диска.
16 Cannot remove current directory (Невозможно удалить текущую директорию)
Генерируется при попытке удалить текущую директорию.
17 Cannot rename across drives (Можно переименовывать файлы только в пределах одного диска)
Вы не можете переименовать файл в файл, находяшиёся на другом диске или в другом разделе.
100 Disk read error (Ошибка чтения с диска)
Генерируется при невозможности произвести чтение с диска. Обычно происходит при попытке чтения данных, после его окончания.
101 Disk write error (Ошибка записи на диск)
Генерируется когда Вы пытаетесь записать данные на переполненый диск.
102 File not assigned (Файл не определён)
Генерируется функциями Reset, Rewrite, Append, Rename и Erase, При передаче в них файловой переменной, для которой не была выполнена функция AssignFile.
103 File not open (Файл не открыт)
Генерируется следующими функциями : Close, Read, Write, Seek, EOf, FilePos, FileSize, Flush, BlockRead, и BlockWrite если файл не был открыт.
104 File not open for input (Файл не открыт для чтения)
Генерируется функциями Read, BlockRead, Eof, Eoln, SeekEof и SeekEoln если файл не был открыт при помощи Reset.
105 File not open for output (Файл не открыт для записи)
Генерируется функцией write если текстовый файл не был открыт при помощи Rewrite.
106 Invalid numeric format(Неправильный числовой формат)
Генерируется когда ожидалось числовое значение, но из текстого файла было прочитано не было.
150 Disk is write-protected (Диск защищён от записи)
(Критическая ошибка)
151 Bad drive request struct length (Неправильная длина структуры запроса)
(Критическая ошибка)
152 Drive not ready (Устройство не готово)
(Критическая ошибка)
154 CRC error in data (Ошибка контрольной суммы в данных)
(Критическая ошибка)
156 Disk seek error (Ошибка низкоуровнего поиска на диске)
(Критическая ошибка)
157 Unknown media type (Неизвестный тип …)
(Критическая ошибка)
158 Sector Not Found (Сектор не найден)
(Критическая ошибка)
159 Printer out of paper (Нет бумаги в принтере)
(Критическая ошибка)
160 Device write fault (Сбой записи устройства)
(Критическая ошибка)
161 Device read fault (Сбой чтения устройства)
(Критическая ошибка)
162 Hardware failure (Сбой железа)
(Критическая ошибка)
200 Division by zero (Деление на ноль)
Приложение пыталось разделить число на ноль.
201 Range check error (Ошибка проверки границ)
Если вы компилировали прогамму с включённой провереой границ, Вы можете получить эту ошибку в следующих случаях:
-
Массив был вызван с индексом, выходящим за декларированые пределы.
-
Попытка присвоить значение переменной, выходящее за декларированые границы (для instance и enumerated типов).
202 Stack overflow error (Переполнение стека)
Стек превысил свой максимально допустимый размер (в этом случае необходимо уменьшить размер локальных переменных), или стек был повреждён. Эта ошибка генерируется только с включённой проверкой стека.
203 Heap overflow error (Переполнение кучи)
Размер кучи превысил максимально возможный размер. Генерируется при попытке выделить память непосредственно функциями New, GetMem и ReallocMem, или когда экземпляр класса или объекта создаётся и памяти не достаточно. Пожалуйста учтите что, по умолчанию, Free Pascal поддерживает увеличение кучи, то есть, если необходимо, будет произведена попытка её увеличения. Как бы то ни было, если размер кучи превысил максимально допустимый системой и
железом, то Вы получите эту ошибку.
204 Invalid pointer operation (Непрваильная операция с указателем)
Будет сгенерирована при вызове функций Dispose или Freemem с неправильным указателем (чаще всего, Nil)
205 Floating point overflow (Максимальная границы числа с плавающей точкой)
Вы попытались использовать или создать слишком большое число с плавающей точкой.
206 Floating point underflow (Минимальная граница числа с плавающей точкой)
Вы попытались использовать или создать слишком маленькое число с плавающей точкой.
207 Invalid floating point operation (Неправильная операция над числами с плавающей точкой)
Может генерироваться если вы попытались получить квадратный корень или логарифм отрицательного числа.
210 Object not initialized (Объект не инициализирован)
Если программа была скомпилирована с включенной проверкой границ, эта ошибка будет сгенерирована при попытке вызвать виртуальный метод до его конструктора.
211 Call to abstract method (Попытка вызова абстрактного метода)
Ваша программа попыталась вызвать абстрактный виртуальный метод. Абстрактные методы должны быть перекрыты, и только перекрытый метод должен быть вызван.
212 Stream registration error (Ошибка регистрации потока)
Генерируется когда неправильный тип регистрируется в модуле objects.
213 Collection index out of range (Индекс элемента коллекции выходит за допустимые границы)
Генерируется когда Вы попытались обратиться к элементу коллекции с выходящим за допустимые границы индексом (модуль objects).
214 Collection overflow error (Переполнение коллекции)
Размер коллекции превысил максимально допустимый размер, а Вы попытались добавить новый элемент (модуль objects).
215 Arithmetic overflow error (Арифметическое переполнение)
Эта ошибка генерируется когда результат операции превысил допустимые границы. В отличие to Turbo Pascal, эта ошибка генерируется только для 32-bit и 64-bit арифметических переполнений. Это происходит согласно тому, что все операнды конвертируются в 32-bit или 64-bit, до того как производить вычисления.
216 General Protection fault (GP Ошибка защиты памяти)
Приложение попыталось обратиться к недопустимому участку памяти. Это может быть вызвано следующими причинами:
-
Попытка получить разуказатель для nil.
-
Попытка получить доступ к выходящему за допустимые границы участку памяти (например, вызов move с неправильной длиной).
217 Unhandled exception occurred (Произошо неизвестное исключение)
Произошло исключение, и для него не существеет хэндла. Модуль sysutils устанавливает handler(менеджер), который отлавливает все исключения, и безопасно выходит в случае обнаружения оного.
219 Invalid typecast (Неправильное приведение типов)
Генерируется когда недопустимое приведение типов производится над классом используя оператор as. Эта ошибка также генерируется, когда объект или класс приводится к недопустимому объекту или классу, и виртуальный метод этого объекта или класса вызывается. Эта последняя ошибка детектируется только с использованием опции -CR компилятора.
227 Assertion failed error (Сбой утверждения)
Утверждение провалено, и процедурная переменная AssertErrorProc не была уcтановлена.
│
العربية (ar) │
English (en) │
español (es) │
suomi (fi) │
français (fr) │
日本語 (ja) │
русский (ru) │
中文(中国大陆) (zh_CN) │
中文(台灣) (zh_TW) │
Введение
Каждый программист должен знать, как работать с файлами. Файлы используются для сохранения данных, т. е. в качестве хранилища данных, таким образом, что они могут быть получены в любой момент, без их воссоздания. Файлы можно использовать для сохранения пользовательских настроек, журналов ошибок, измерение или вычисление результатов, и многое другое. В данном разделе описываются основы использования файлов.
Процедурный стиль
Это довольно старый стиль, использующейся ещё во времена, когда Pascal не был объектно-ориентированным языком. Суть его в том, что задается тип файла, определяющий, какие будут храниться в нем данные. Для этого, используется конструкция вида: file of <тип данных>, где <тип данных> — название типа, который хранит в себе файл. Помимо стандартных типов (integer, extended, char и т.д.), существует особый тип — TextFile. Он определят, что каждая строка заканчивается специальным(ми) символом(ами) конца строки (См. LineEnding). Эти файлы могут быть открыты и отредактированы внутри среды Lazarus или в любом другом текстовом редакторе.
Ниже представлены примеры создания собственных типов файлов:
... type TIntegerFile = file of integer; // Позволяет писать только целые числа в файл TExtendedFile = file of extended; // Позволяет писать только дробные цифры в файл TCharFile = file of char; // Позволяет писать только одиночные символы в файл
Обработка ошибок ввода/вывода
Параметр компилятора обработки ошибок ввода/вывода указывает, как должна вести себя программа при возникновении ошибки в процессе работы с файлами: вызвать исключение или хранить результат операции ввода/вывода в специальной переменной IOResult.
Это задаётся с помощью специальной директивы компилятора:
{$I+} // В случаи ошибки будет вызвано исключение EInOutError (по умолчанию) {$I-} // Подавлять ошибки ввода-вывода: проверьте переменную IOResult для получения кода ошибки.
В случаи подавления ошибок ввода-вывода ({$I-}) результат операции с файлом будет храниться в переменной IOResult типа cardinal (числовой тип). Каждое число, хранимое в IOResult определяет тип возникшей ошибки(подробнее: [1]).
Процедуры работы с файлами
Эти процедуры и функции находятся в модуле system. Для более подробной информации смотрите документацию FPC:
ссылка на модуль 'System'.
- AssignFile (не допускайте использование процедуры Assign) — Связывает переменную с файлом
- Append — Открывает существующий файл для записи данных в конец и их редактирования
- BlockRead — Чтение данных из не типизированного файла в память
- BlockWrite — Запись данных из памяти в не типизированный файл
- CloseFile (не допускайте использование процедуры Close) — Закрыть открытый файл
- EOF — Проверка наличия конца файла
- Erase — Стереть файл с диска
- FilePos — Получить позицию в файле
- FileSize — Получить размер файла
- Flush — Записать файловый буфер на диск
- IOResult — Возвращает результат последней операции вводавывода
- Read — Считать из текстового файла
- ReadLn — Считать из текстового файла и перейти к следующей строке
- Reset — Открыть файл для чтения
- Rewrite — Создать и открыть файл для записи
- Seek — Изменить позицию в файле
- SeekEOF — Переместить позицию в файле в его конец
- SeekEOLn — Переместить позицию в файле в конец строки
- Truncate — Удалить все данные, после текущей позиции
- Write — Записать переменную в файл
- WriteLn — Записать переменную в текстовый файл и перейти к новой строке
Пример
Пример работы с текстовым файлом (тип TextFile):
program CreateFile; uses Sysutils; const C_FNAME = 'textfile.txt'; var tfOut: TextFile; begin // Связываем имя файла с переменной AssignFile(tfOut, C_FNAME); // Использовать исключение для перехвата ошибок (это по умолчанию и указывать не обязательно) {$I+} // Для обработки исключений, используем блок try/except try // Создать файл, записать текст и закрыть его. rewrite(tfOut); writeln(tfOut, 'Пример текстового файла!'); writeln(tfOut, 'Пример записи числа: ', 42); CloseFile(tfOut); except // Если ошибка - отобразить её on E: EInOutError do writeln('Ошибка обработки файла. Детали: ', E.ClassName, '/', E.Message); end; // Выводим результат операции и ожидаем нажатие Enter writeln('Файл ', C_FNAME, ' создан. Нажмите ВВОД для выхода.'); readln; end.
Теперь откройте файл в любом текстовом редакторе и вы увидите, что пример текста, записан в нем!
Вы можете проверить работу обработки ошибок, установив атрибут файла «только для чтения» и снова запустив программу.
Обратите внимание, что в примере используется блок try/except. Данный способ позволяет выполнять несколько операций с файлами и использовать обработку исключений.
Вы также можете использовать режим {$I-}, но тогда вам придется проверять переменную IOResult после каждой операции с файлами для контроля ошибок.
Ниже приведен пример записи текста в конец файла:
program AppendToFile; uses Sysutils; const C_FNAME = 'textfile.txt'; var tfOut: TextFile; begin // Связываем имя файла с переменной AssignFile(tfOut, C_FNAME); // Для обработки исключений, используем блок try/except try // Открыть файл для записи в конец, записать текст и закрыть его. append(tfOut); writeln(tfOut, 'Ещё пример текстового файла!'); writeln(tfOut, 'Результат 6 * 7 = ', 6 * 7); CloseFile(tfOut); except on E: EInOutError do writeln('Ошибка обработки файла. Детали: ', E.Message); end; // Выводим результат операции и ожидаем нажатие Enter writeln('Файл ', C_FNAME, ' возможно содержит больше текста. Нажмите ВВОД для выхода.'); readln; end.
Чтение текстового файла:
program ReadFile; uses Sysutils; const C_FNAME = 'textfile.txt'; var tfIn: TextFile; s: string; begin // Вывод некой информации writeln('Чтение содержимого файла: ', C_FNAME); writeln('========================================='); // Связываем имя файла с переменной AssignFile(tfIn, C_FNAME); // Для обработки исключений, используем блок try/except try // Открыть файл для чтения reset(tfIn); // Считываем строки, пока не закончится файл while not eof(tfIn) do begin readln(tfIn, s); writeln(s); end; // Готово. Закрываем файл. CloseFile(tfIn); except on E: EInOutError do writeln('Ошибка обработки файла. Детали: ', E.Message); end; // Выводим результат операции и ожидаем нажатие Enter writeln('========================================='); writeln('Файл ', C_FNAME, ' считан. Нажмите ВВОД для выхода.'); readln; end.
Объектный стиль
В дополнение к старому методу обработки файлов, упомянутому выше процедурному стилю, существует новая система, которая использует концепции потоков (данных) на более высоком уровне абстракции. Это означает, что данные могут считываться или записываться в любом месте (диск, память, аппаратные порты и т. д.) через один универсальный интерфейс.
Кроме того, большинство классов обработки строк, могут иметь возможность загружать/сохранять содержимое из/в файл. Эти методы обычно называются SaveToFile и LoadFromFile.
Двоичные файлы
Для прямого доступа к файлам, так же удобно использовать класс TFileStream. Этот класс представляет собой инкапсуляцию системных процедур FileOpen, FileCreate, FileRead, FileWrite, FileSeek и FileClose, расположенных в модуле SysUtils.
Процедуры ввода-вывода
В приведенном ниже примере обратите внимание, что обработка действий с файлом, расположена внутри блока try..except. Поэтому обработка ошибок происходит так же, как в случаи использования процедур работы с файлами в классическом Pascal.
program WriteBinaryData; {$mode objfpc} uses Classes, Sysutils; const C_FNAME = 'binarydata.bin'; var fsOut : TFileStream; ChrBuffer: array[0..2] of char; begin // Создать некоторые случайные данные, которые будут храниться в файле ChrBuffer[0] := 'A'; ChrBuffer[1] := 'B'; ChrBuffer[2] := 'C'; // Перехват ошибок в случае, если файл не может быть создан try // Создать экземпляр потока файла, записать в него данные и уничтожить его, чтобы предотвратить утечки памяти fsOut := TFileStream.Create( C_FNAME, fmCreate); fsOut.Write(ChrBuffer, sizeof(ChrBuffer)); fsOut.Free; // Обработка ошибки except on E:Exception do writeln('Файл ', C_FNAME, ' не создан, так как: ', E.Message); end; // Выводим результат операции writeln('Файл ', C_FNAME, ' создан. Нажмите ВВОД для выхода.'); //Ожидаем нажатие Enter readln; end.
Вы так же можете загрузить весь файл в память, если его размер существенно меньше, чем имеющийся системной памяти. Если файл превышает размер системной памяти, то ваша операционная система начнет использовать файл подкачки, снижая скорость работы с файлом.
program ReadBinaryDataInMemoryForAppend; {$mode objfpc} uses Classes, Sysutils; const C_FNAME = 'binarydata.bin'; var msApp: TMemoryStream; begin // Создаем поток в памяти msApp := TMemoryStream.Create; // Перехват ошибок в случае их возникновения try // Считать данные в память msApp.LoadFromFile(C_FNAME); // Переходим в конец данных msApp.Seek(0, soEnd); // Запись неких данных в поток msApp.WriteByte(68); msApp.WriteAnsiString('Некий текст'); msApp.WriteDWord(671202); // Запись данных на диск (файл будет перезаписан) msApp.SaveToFile(C_FNAME); // Обработка ошибки except on E:Exception do writeln('Файл ', C_FNAME, ' не удалось считать или записать, так как: ', E.Message); end; // Освобождаем память и уничтожаем объект msApp.Free; // Выводим результат операции и ожидаем нажатие Enter writeln('Файл ', C_FNAME, ' дописан. Нажмите ВВОД для выхода.'); readln; end.
Для работы с файлами большого объёма, рекомендуется использовать буфер, например в 4096 байт.
var TotalBytesRead, BytesRead : Int64; Buffer : array [0..4095] of byte; // или, array [0..4095] of char FileStream : TFileStream; try FileStream := TFileStream.Create; FileStream.Position := 0; // Установим позицию в начало файла while TotalBytesRead <= FileStream.Size do // Пока объем считанных данных меньше размера файла begin BytesRead := FileStream.Read(Buffer,sizeof(Buffer)); // Считать 4096 байт данных inc(TotalBytesRead, BytesRead); // Увеличиваем TotalByteRead на размер буфера, т.е. 4096 байт // Что-то делаем с буфером данных end;
Копирование файла
Теперь,зная методы работы с файлами, мы можем реализовать простую функцию копирования файла, скажем FileCopy.(такой функции нет в FreePascal, хотя Lazarus её имеет copyfile):
program FileCopyDemo; // Пример функции FileCopy {$mode objfpc} uses classes; const fSource = 'test.txt'; fTarget = 'test.bak'; function FileCopy(Source, Target: string): boolean; // Копируем файл с путем в Source в файл с путем Target. // Кэшируем весь файл в память. // В случаи успеха возвращаем true, в случаи ошибки - false. var MemBuffer: TMemoryStream; begin result := false; MemBuffer := TMemoryStream.Create; try MemBuffer.LoadFromFile(Source); MemBuffer.SaveToFile(Target); result := true except //Подавляем исключение; результатом функции является значение false по умолчанию end; // Очистка MemBuffer.Free end; // Пример использования begin If FileCopy(fSource, fTarget) then writeln('Файл ', fSource, ' скопирован в ', ftarget) else writeln('Файл ', fSource, ' не скопирован в ', ftarget); readln() end.
Обработка текстовых файлов (TStringList)
Для текстовых файлов можно использовать класс TStringList, чтобы загрузить весь файл в память и иметь легкий доступ к его строкам. Вы также можете записать StringList обратно в файл:
program StringListDemo; {$mode objfpc} uses Classes, SysUtils; const C_FNAME = 'textfile.txt'; var slInfo: TStringList; begin // Создаем TStringList для обработки текстового файла slInfo := TStringList.Create; // Для обработки исключений, используем блок try/except try // Загружаем файл в память slInfo.LoadFromFile(C_FNAME); // Добавляем некие строки slInfo.Add('Некая строка'); slInfo.Add('Ещё одна строка.'); slInfo.Add('Всё, хватит.'); slInfo.Add('Сейчас ' + DateTimeToStr(now)); // Записать содержимое на диск, заменив исходное содержимое slInfo.SaveToFile(C_FNAME); except // Обработка ошибки on E: EInOutError do writeln('Произошла ошибка обработки файла. Причина: ', E.Message); end; // Очистка slInfo.Free; // Выводим результат операции и ожидаем нажатие Enter writeln('Файл ', C_FNAME, ' обновлен. Нажмите ВВОД для выхода.'); readln; end.
Демо: сохранить одну строку в файл
Для того, чтобы сохранить одну строку в файл, вы можете воспользоваться процедурой, описанной ниже.
program SaveStringToPathDemo; {$mode objfpc} uses Classes, sysutils; const C_FNAME = 'textstringtofile.txt'; // SaveStringToFile: функция для хранения строк текста в файле на диске. // Если результат функции равен True, то строка была написана // Иначе произошла ошибка function SaveStringToFile(theString, filePath: AnsiString): boolean; var fsOut: TFileStream; begin // По умолчанию результат неудачный result := false; // Записать данную строку в файл, перехватывая ошибки в процессе записи. try fsOut := TFileStream.Create(filePath, fmCreate); fsOut.Write(theString[1], length(theString)); fsOut.Free; // На данном этапе известно, что запись прошла успешно. result := true except on E:Exception do writeln('Строка не записана. Детали: ', E.ClassName, ': ', E.Message); end end; // // Основная программа // begin // Пытаемся сохранить текст в файл и выводим результат операции if SaveStringToFile('>> этот текст сохраняется <<', C_FNAME) then writeln('Текст успешно записан в файл.') else writeln('Не удалось сохранить текст в файл.'); // Ждем нажатия Enter readln end.
Смотрите так же
- CopyFile — функция Lazarus, которая копирует файл
- File
7.4 Обработка текстовых файлов в языке Free Pascal
При работе с текстовыми файлами следует учесть следующее:
- Действие процедур reset, rewrite, close, rename, erase и функции eof аналогично их действию при работе с компонентными (типизированными) файлами.
- Процедуры seek, trunсate и функция filepos не работают с текстовыми файлами.
- Можно пользоваться процедурой открытия текстового файла append(f), где f — имя файловой переменной. Эта процедура служит для открытия файла в режиме дозаписи в конец файла. Она применима только к уже физически существующим файлам, открывает и готовит их для добавления информации в конец файла.
- Запись и чтение в текстовый файл осуществляются с помощью процедур write, writeln, read, readln следующей структуры:
read ( f, x1, x2, x3,…, xn );
read ( f, x );
readln ( f, x1, x2, x3,…, xn );
readln ( f, x );
write ( f, x1, x2, x3,…, xn );
write ( f, x );
writeln ( f, x1, x2, x3,…, xn );
writeln ( f, x );
В этих операторах f — файловая переменная. В операторах чтения (read, readln) x, x1, x2, x3,…, xn — переменные, в которые происходит чтение из файла. В операторах записи write, writeln x, x1, x2, x3,…, xn — переменные или константы, информация из которых записывается в файл.
Есть ряд особенностей при работе операторов write, writeln, read, readln с текстовыми файлами. Имена переменных могут быть целого, вещественного, символьного и строкового типа. Перед записью данных в текстовый файл с помощью процедуры write происходит их преобразование в тип string. Действие оператора writeln отличается тем, что после указанных переменных и констант в файл записывается символ «конец строки».
При чтении данных из текстового файла с помощью процедур read, readln происходит преобразование из строкового типа к нужному типу данных. Если преобразование невозможно, то генерируется код ошибки, значение которого можно узнать, обратившись к функции IOResult. Компилятор Free Pascal позволяет генерировать код программы в двух режимах: с проверкой корректности ввода-вывода и без неё.
В программу может быть включен ключ режима компиляции. Кроме того, предусмотрен перевод контроля ошибок ввода-вывода из одного состояния в другое:
- {$I+} — режим проверки ошибок ввода-вывода включён;
- {$I-} — режим проверки ошибок ввода-вывода отключён.
По умолчанию, как правило, действует режим {$I+}. Можно многократно включать и выключать режимы, создавая области с контролем ввода и без него. Все ключи компиляции описаны в приложении.
При включённом режиме проверки любая ошибка ввода-вывода будет фатальной, программа прервётся, выдав номер ошибки.
Если убрать режим проверки, то при возникновении ошибки ввода-вывода программа не будет останавливаться, а продолжит работу со следующего оператора. Результат операции ввода-вывода будет неопределён.
Для опроса кода ошибки лучше пользоваться специальной функцией IOResult, но необходимо помнить, что опросить её можно только один раз после каждой операции ввода или вывода: она обнуляет своё значение при каждом вызове. IOResult возвращает целое число, соответствующее коду последней ошибки ввода-вывода. Если IOResult=0, то при вводе-выводе ошибок не было, иначе IOResult возвращает код ошибки. Некоторые коды ошибок приведены в табл. 7.9.
Таблица
7.9.
Коды ошибок операций ввода-вывода
Код ошибки | Описание |
---|---|
2 | файл не найден |
3 | путь не найден |
4 | слишком много открытых файлов |
5 | отказано в доступе |
12 | неверный режим доступа |
15 | неправильный номер диска |
16 | нельзя удалять текущую директорию |
100 | ошибка при чтении с диска |
101 | ошибка при записи на диск |
102 | не применена процедура AssignFile |
103 | файл не открыт |
104 | файл не открыт для ввода |
105 | файл не открыт для вывода |
106 | неверный номер |
150 | диск защищён от записи |
Рассмотрим несколько практических примеров обработки ошибок ввода-вывода:
- При открытии проверить, существует ли заданный файл и возможно ли чтение данных из него.
assign ( f, ’ abc. dat ’ ); {$I-} reset ( f ); {$I+} if IOResult<>0 then writeln ( ’файл не найден или не читается ’ ) else begin read ( f,... ); close ( f ); end;
- Проверить, является ли вводимое с клавиатуры число целым.
var i : integer; begin {$I-} repeat write ( ’введите целое число i ’ ); readln ( i ); until ( IOResult =0); {$I+} {Этот цикл повторяется до тех пор, пока не будет введено целое число.} end.
При работе с текстовым файлом необходимо помнить специальные правила чтения значений переменных:
- Когда вводятся числовые значения, два числа считаются разделёнными, если между ними есть хотя бы один пробел, или символ табуляции, или символ конца строки.
- При вводе строк начало текущей строки идёт сразу за последним, введённым до этого символом. Вводится количество символов, равное объявленной длине строки. Если при чтении встретился символ «конец строки», то работа с этой строкой заканчивается. Сам символ конца строки является разделителем и в переменную никогда не считывается.
- Процедура readln считывает значения текущей строки файла, курсор переводится в новую строку файла, и дальнейший ввод осуществляется с неё.
В качестве примера работы с текстовыми файлами рассмотрим следующую задачу.
ЗАДАЧА 7.8. В текстовом файле abc.txt находятся матрицы и и их размеры. Найти матрицу , которую дописать в файл abc.txt.
Сначала создадим текстовый файл abc.txt следующей структуры: в первой строке через пробел хранятся размеры матрицы (числа N и M), затем построчно хранятся матрицы A и B.
Рис.
7.14.
Файл abc.txt
На рис. 7.14 приведён пример файла abc.txt, в котором хранятся матрицы A(4,5) и B(4,5).
Текст консольного приложения решения задачи 7.8 с комментариями приведён ниже.
program Project1; {$mode objfpc}{$H+} uses Classes, SysUtils { you can add units after this }; var f : Text; i, j, N,M: word; a, b, c : array [ 1.. 1000, 1.. 1000 ] of real; begin //Связываем файловую переменную f с файлом на диске. AssignFile ( f, ’ abc. t x t ’ ); //Открываем файл в режиме чтения. Reset ( f ); //Считываем из первой строки файла abc.txt значения N и M. Read( f,N,M); //Последовательно считываем элементы матрицы А из файла. for i :=1 to N do for j :=1 to M do read ( f, a [ i, j ] ); //Последовательно считываем элементы матрицы B из файла. for i :=1 to N do for j :=1 to M do read ( f, b [ i, j ] ); //Формируем матрицу C=A+B. for i :=1 to N do for j :=1 to M do c [ i, j ] : = a [ i, j ]+b [ i ] [ j ]; //Закрываем файл f. CloseFile ( f ); //Открываем файл в режиме дозаписи. Append( f ); //Дозапись матрицы C в файл. for i :=1 to N do begin for j :=1 to M do //Дописываем в файл очередной элемент матрицы и пробел в //текстовый файл. write ( f, c [ i, j ] : 1 : 2, ’ ’ ); //По окончании вывода строки матрицы переходим на новую //строку в текстовом файле. writeln ( f ); end; //Закрываем файл. CloseFile ( f ); end.
После работы программы файл abc.txt будет примерно таким, как показано на рис. 7.15.
Рис.
7.15.
Файл abc.txt после дозаписи матрицы C
Компилятор Турбо Паскаля позволяет генерировать выполнимый код в двух режимах: с проверкой корректности ввода-вывода и без нее. В среде программирования этот режим включается в меню
— 262 —
Options/Compiler/IO-checking. При включении в программу ключ режима компиляции обозначается как
{$I+} — режим проверки включен;
{$I-} — режим отключен.
По умолчанию, как правило, действует режим $I+. Этот ключ компиляции имеет локальную сферу влияния. Можно многократно включать и выключать режим, вставляя в текст программы конструкции {$I+} и {SI-}, тем самым создавая области с контролем ввода-вывода и без него.
При включенном режиме проверки любая ошибка ввода-вывода будет фатальной: программа прервется, выдав номер ошибки. Возможные номера ошибок ввода-вывода находятся в диапазоне от 2 до 200 ( от 2 до 99 — это коды ошибок DOS, от 100 до 149 — ошибки, диагностируемые самой программой, и от 150 до 200 — критические аппаратные ошибки). Расшифровка кодов ошибок с краткими комментариями приведена в табл. 12.6 в конце этого раздела.
Если отключить режим проверки, то при возникновении ошибки ввода-вывода программа уже не будет прерываться, а продолжит работу со следующего оператора. Результат операции ввода-вывода, вызвавшей ошибку, будет неопределен. При этом код ошибки будет сохранен в предопределенной системной переменной InOutRes. Однако для опроса этого кода лучше пользоваться специальной функцией Турбо Паскаля.
Дополнительные функции работы с файлами
Модуль |
|
ChDir |
Выполняет |
MkDir |
Создает |
RmDir |
Удаляет |
GetDir |
Получить |
Модуль |
|
DiskFree |
Число |
DiskSize |
Размер |
GetFAttr |
Получение |
SetFAttr |
Задание |
FSplit |
Получение |
FExpand |
Формирование |
FSearch |
Поиск |
FindFirst |
Поиск |
FindNext |
Поиск |
Прототипы
процедур FindFirst
и FindNext
имеют вид:
FindFirst(Path:
String; Attrib: Word; Var SR: SearchRec);
FindNext(Var
SR:
SearchRec);
Для
работы с этими подпрограммами требуются
следующие предопределенные описания:
-
Константы
Const
ReadOnly
= $01; только
для чтения
Hidden = $02; скрытый
SysFile =
$04; системный (непереносимый)
Volume ID = $08; метка
диска
Directory =
$10; подкаталог
Archive = $20; архивный
AnyFile = $3F; сумма
всех предыдущих
Эти атрибуты можно
складывать или вычитать (из anyfile).
-
Переменная
DOSError.
Она используется для анализа ошибок
MS
DOS.
Значение этой переменной, равное нулю,
соответствует отсутствию ошибки. Смысл
некоторых ненулевых кодов следующий:
2
– файл не найден
3
– маршрут не найден
5
– доступ к файлу запрещен
6
– неправильная обработка
8
– недостаточно памяти
10
– неверные установки значений параметров
среды
11
– неправильный формат
18
– файлов нет
При
работе процедуры FindFirst
возможны ошибки с номерами 2 и 18, а при
работе FindNext
– только 18.
3)
Тип
Type
SearchRec
= record
Fill: array[1..21] of byte; {системное поле}
attr: byte; {байт атрибутов}
time: longint; {время
создания}
size: longint; {размер
файла}
name: string[12]; {имя файла}
end;
Поля
переменной этого типа содержат информацию
о последнем файле, найденном с помощью
FindFirst
и FindNext.
Процедура
FindFirst
при заданных имени файла и атрибутах
должна вызываться лишь один раз. Она
записывает в поля переданной ей переменной
SR
типа SearchRec
информацию о первом найденном файле,
удовлетворяющем заданным условиям. Эта
информация в дальнейшем будет
использоваться процедурой FindNext,
которая всегда вызывается после FindFirst
и заполняет поля переменной SR
информацией о следующем найденном
файле.
Контроль
работы этих процедур ведется с помощью
переменной DOSError:
если файла нет, то DOSError<>0.
Обработка ошибок ввода-вывода
Все рассмотренные
ранее программы были написаны так, что
возможные ошибки ввода-вывода
игнорировались. Однако реально это не
так. В ТР стандартной реакцией на наличие
ошибок в вашей программе является
следующее: ваша программа аварийно
завершается и выдает сообщение:
Runtime
error
<номер> <смещение>.
Такое сообщение
буде полезно вам как программистам при
поиске места и причины ошибки в программе.
Однако показывать такое сообщение
пользователю вашей программы будет не
совсем дружественно.
Для того, чтобы
ваша программа из-за ошибки аварийно
не завершалась и для того, чтобы не
пугать пользователей непонятными им
сообщениями, вам необходимо перехватить
инициативу по обработке ошибок у системы
и писать собственные обработчики ошибок
стадии выполнения (исключений). Традиционно
обработка ошибок в программах
осуществляется с помощью установки
флагов (в
случае ошибки) и последующего анализа
этих флагов. Для перехвата ошибок
ввода-вывода на Паскале необходимо:
-
Специальным
образом оформить каждый фрагмент
программы, которые потенциально могут
вызвать ошибку. К таким фрагментам
относятся — открытие файда, чтение из
файла, запись в файл. -
При наличии такого
специального оформления необходимо
по завершению фрагмента проверить:
была ошибка или нет. Если была, то вы
должны выполнить ее обработку (хотя бы
вывести свое сообщение).
Пример:
reset(f);
при попытки открытия
файла физически файл может отсутствовать
на диске. Этот оператор в программе
является потенциальным источником
ошибки.
Специальное
оформление потенциально опасных участков
программы состоит в том, что
вы должны
как бы завернуть каждый опасный участок
в специальный код: выше
и ниже опасного фрагмента программы
вы должны
расположить две директивы компилятора:
{$I-}
— указывает на то, что необходимо
отключить системный контроль ошибок
reset(f);
{$I+}
— указывает на то, что необходимо включить
системный контроль ошибок
При наличии
директивы компилятора {$I-}
даже при наличии ошибок в/в программа
аварийно не завершается и ход выполнения
программы не нарушается.
Замечание:
По умолчанию действует директива {$i+}.
Контроль ошибок
в/в производится с помощью функции
IOResult
. Если ошибка имеет место, то значение
этой функции отлично от нуля. Поэтому
типичный шаблон обработки ошибки
ввода-вывода имеет вид:
If
IOResult
<> 0 Then
{обработка ошибки};
Обычно обработка
ошибки сводится к сообщению об ошибки
и завершению вашей программы (с помощью
процедуры HALT
или EXIT).
Замечание:
Опросить функцию IOResult
можно лишь
один раз
после каждой операции ввода-вывода,
т.к. она обнуляет свое значение перед
каждым вызовом. Поэтому целесообразно
сохранять значение, возвращенное
IOResult,
в специально выделенной переменной.
Пример.
{$I-}
reset(f);
{$I+}
If
IOResult <> 0
then
begin
Writeln(‘Ошибка
открытия
файла’);
Halt;
end;
Соседние файлы в папке WORD
- #
15.04.2015439.06 Кб306.docx
- #
- #
- #
- #
- #
- #
- #
- #
- #
- #
В этом разделе обсуждаются разнообразные,
важные в практическом отношении, примемы
программирования.
1. Обработка ошибок ввода-вывода
В одном из предыдущих разделов был рассмотрен
фрагмент программы, демонстрирующий контроль за
вводимой информацией и не допускающий ввод
некорректных данных. Повторим здесь этот
фрагмент:
PROGRAM CheckInputData_1;
USES CRT;
VAR
x : Real;
BEGIN
ClrScr;
REPEAT
Write(‘Введите число в интервале от 0 до
100: ‘);
Read(x);
if not((x>=0)and(x<=100))
then writeln(‘Ошибка при вводе
числа!’);
UNTIL (x>=0)and(x<=100);
…
…
END.
Приведенная программа не допускает ввода числа
меньше нуля или больше ста. А что произойдет, если
вместо числа ввести (случайно) какой-либо иной
символ? Скорее всего это приведет к
возникновению фатальной (т.е. ведущий к
прекращению работы программы) ошибки
ввода-вывода: Error 106: Invalid numeric format. Этого можно избежать, если
воспользоваться приемом, описанным ниже.
Сначала немного теории. Компилятор
языка Турбо Паскаль позволяет генерировать
выполнимый (машинный) код в
дух режимах: с проверкой корректности
ввода-вывода и без нее. В среде программирования
этот режим включается в меню Options – Compiler –
I/O Checking. Режимом компиляции
можно управлять непосредственно в тексте
программы с помощью ключа компиляции $I
{$I+} – режим проверки включен;
{$I-} – режим отключен.
По умолчанию, как правило, действует режим $I+. Этот ключ компиляции имеет
локальную сферу влияния. Можно многократно
включать и выключать режим, вставляя в текст
программы конструкции {$I+} и {$I-},
тем самым создавая области с
контролем ввода-вывода и без него.
При включенном режиме проверки любая ошибка
ввода-вывода будет фатальной: программа
прервется, выдав номер ошибки. Если отключить
режим проверки, то при возникновении ошибки
ввода-вывода программа уже не будет прерываться,
а продолжит работу со следующего оператора.
Результат операции ввода-вывода, вызвавший
ошибку, будет неопределен. При этом код ошибки
будет сохранен и в последствии его можно узнать с
помощью специальной функции IOResult. Эта функция возвращает целое число,
соответствующее коду последней ошибки
ввода-вывода. Если же операция ввода-вывода
прошла без сбоев, то функция вернет значение 0. Опросить функцию IOResult можно только один раз, ибо она
обнуляет свое значение при каждом вызове. Обычно
это обходят запоминанием значения функции в
какой-либо переменной.
Итак, для того чтобы рассмотренная выше
программа не давала сбоев при вводе, необходимо
отключить режим проверки ошибок ввода-вывода на время работы
процедуры Read, а затем
проанализировать значение функции IOResult:
PROGRAM CheckInputData_2;
USES CRT;
VAR
x : Real;
err : Integer;
BEGIN
ClrScr;
REPEAT
Write(‘Введите число в интервале от 0 до 100: ‘);
{$I-}
Read(x);
{$I+}
err := IOResult;
if not((x>=0) and (x<=100)) or (err<>0)
then writeln(‘Ошибка при вводе числа!’);
UNTIL (x>=0) and (x<=100) and (err=0);
…
…
END.
Возможность управлять режимом обработки
ошибок и наличие функции IOResult
позволяет писать программы, никогда не дающие
сбоев при вводе или выводе данных и при работе с
файлами.
2. Управление программой с помощью меню
При написании больших и не очень больших
программ, выполняющих различные действия,
полезно сделать так, чтобы у пользователя была
возможность выбрать тот или иной режим работы с
программой. Например, если программа направлена
на решение некоторой физической задачи, то она
может иметь по крайней мере три режима работы: 1)
ввод и модификация параметров задачи; 2)
собственно вычисления; 3) представление
результатов (например, построение графиков
рассчитанных зависимостей). Организация выбора
режимов работы может быть сделана с помощью меню.
Меню, в данном случае, — это перечень команд или
режимов работы, которые можно выбрать тем или
иным способом. В простейшем случае, меню может
быть представлено на экране нумерованным списком. Выбор того или иного пункта
меню осуществляется вводом числа,
соответствующего номеру пункта. В более сложных
случаях выбор пункта меню может осуществляться
перемещением (с помощью клавиатуры или “мыши”)
курсора-подсветки, а активизация выбранного
пункта – нажатием на клавишу “Enter” или щелчком кнопки мыши.
Рассмотрим в качестве примера структуру
программы, содержащей простейшее меню в виде
нумерованного списка.
PROGRAM Example_of_Menu;
USES CRT;
VAR Ch : Char;
PROCEDURE ChangeParam;
BEGIN
END;
PROCEDURE Calculation;
BEGIN
END;
PROCEDURE ShowGraphic;
BEGIN
END;
BEGIN
repeat
ClrScr;
GotoXY(30,2);
Write(‘НАЗВАНИЕ ПРОГРАММЫ’);
GotoXY(28,6);
Write(‘- Меню режимов работы -’);
GotoXY(20,8); Write(‘1 — Ввод и изменение
параметров’);
GotoXY(20,10); Write(‘2 — Вычисление’);
GotoXY(20,12); Write(‘3 — Построение графика’);
GotoXY(20,14); Write(‘4 — Завершение работы’);
GotoXY(15,18);
Write(‘Для выбора режима работы нажмите
клавишу [1..4]: ’);
repeat
Ch := ReadKey;
until Ch in [’1’,’2’,’3’,’4’];
case Ch of
‘1’ : ChangeParam;
‘2’ : Calculation;
’3’ : ShowGraphic;
’4’ : Halt;
end; {case}
until false;
END.
Права на материал принадлежат их авторам
Вернуться на главную страницу