Синтаксические ошибки delphi

При компиляции Delphi программ могут возникать различные виды ошибок. Некоторые из них включают:

  1. Синтаксические ошибки: возникают, когда в коде программы есть синтаксические ошибки, такие как неправильное использование ключевых слов, неверное написание идентификаторов, отсутствие точек с запятой в конце строк и т.д.
  2. Ошибки типа: возникают, когда в программе используется неправильный тип данных или когда типы данных не совместимы друг с другом.
  3. Ошибки логики: возникают, когда в программе есть ошибки в логике, например, когда программист допустил ошибку при расчете значения или при написании условия.
  4. Ошибки времени выполнения: возникают во время выполнения программы, когда происходят ошибки, связанные с работой с памятью, вводом-выводом или другими системными функциями.
  5. Ошибки линковки: возникают, когда компилятор не может найти необходимые библиотеки или объектные файлы, необходимые для построения исполняемого файла.
  6. Ошибки взаимодействия с ОС: возникают, когда программа пытается выполнить операции, которые не разрешены операционной системой, например, когда программа пытается получить доступ к защищенной области памяти.
  7. Ошибки ввода-вывода: возникают, когда программа не может прочитать или записать данные из файла или с других устройств ввода-вывода.

Это не полный список ошибок, которые могут возникать при компиляции Delphi программ, но эти ошибки являются наиболее распространенными.

Как исправить ошибки при компиляции Delphi программ?

Исправление ошибок при компиляции Delphi программ зависит от типа ошибки. Вот несколько общих советов, которые могут помочь в исправлении ошибок:

  1. Внимательно прочтите сообщение об ошибке: сообщение об ошибке обычно содержит информацию о том, какая ошибка возникла и в какой части кода. Внимательное прочтение сообщения об ошибке может помочь быстро определить причину ошибки.
  2. Используйте справочник Delphi: справочник Delphi содержит информацию о ключевых словах, функциях и типах данных, которые могут быть полезны при исправлении ошибок.
  3. Используйте отладчик: отладчик может помочь определить место, где возникает ошибка, и отследить значения переменных и состояние программы в этом месте.
  4. Проверьте правильность написания кода: ошибки могут возникать из-за неправильного написания кода, так что проверьте свой код на наличие синтаксических ошибок и ошибок типа.
  5. Проверьте зависимости: если ошибка связана с линковкой, убедитесь, что все необходимые библиотеки и объектные файлы доступны и правильно подключены.
  6. Проверьте правильность использования API: если ошибка связана с взаимодействием с операционной системой, убедитесь, что вы используете API правильно и не пытаетесь выполнить операции, которые не разрешены ОС.
  7. Обратитесь к сообществу: если вы не можете исправить ошибку самостоятельно, вы можете обратиться за помощью к сообществу Delphi, например, на форумах (dropcode.ru, devhubby.com) или в группах социальных сетей.

В целом, исправление ошибок при компиляции Delphi программ зависит от специфики конкретной ошибки, поэтому важно понимать, как работает ваша программа и какие функции и библиотеки вы используете.

Отладка
программ

  1. Виды ошибок

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

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

Динамические ошибки возникают при
выполнении программы и являются
следствием неправильной работы
операторов, процедур, функций или методов
программы, а также операционной системы.
Обычно такого рода ошибки возникают
при отдельных значениях переменных,
констант и т.д., при других же значениях
программа работает правильно. Динамические
ошибки называют также ошибками времени
выполнения
(Runtime errors).
В Delphi для обработки
динамических ошибок вводится понятие
исключительной ситуации. Исключительная
ситуация состоит в нарушении условий
выполнения программы, вызывающем
прерывание или полное прекращение
работы программы. Обработка исключительной
ситуации состоит в нейтрализации
динамической ошибки, вызвавшей ее.

  1. Синтаксические ошибки

Обнаруживаются компилятором автоматически.
Сообщения о найденных ошибках отображаются
в нижней части редактора, в небольшом
окне. При двойном щелчке на строке с
сообщением об ошибке система Delphi
переключается в редактор, где выделит
светом строку, в которой эта ошибка
обнаружена. Само сообщение описывает
смысл ошибки, чтобы можно было понять
причину ошибки.

  1. Логические ошибки

Существует несколько приемов выявления
и устранения логических ошибок. Они
используются программистами, как правило
в комбинации друг с другом.

За наиболее часто встречающимися
ошибками может следить сама программа.
Для этого в настройках проекта
(Project/Options)
– на вкладке Compiler
надо выполнить следующие действия.

  • На
    панели Code generation
    (Генерация машинного кода) сбросить
    флажок Optimization (Оптимизация).
    Когда компилятор создает оптимизированный
    код, он нередко вносит существенные
    улучшения в детали алгоритма,
    реализованного на Паскале. Например,
    могут не использоваться промежуточные
    переменные, в таком случае программист
    в процессе отладки не сумеет узнать
    значение этой переменной.

  • На
    панели Runtime errors
    (Ошибки времени выполнения) должны быть
    установлены флажки Range
    Checking (Контроль выхода
    индекса за границы массива), I/O
    Checking (Контроль ошибок
    водавывода) и
    Overflow checking
    (Контроль переполнения при целочисленных
    операциях).

  • На
    панели Debugging (Отладка)
    установить флажки Debug
    information (Добавление
    отладочной информации), Local
    symbols (Просмотр значений
    локальных переменных), Reference
    info (Просмотр структуры
    кода), Assertions (Включение
    процедуры Assert в машинный
    код) и Use Debug
    DCUs (Использование
    отладочных версий стандартных модулей
    библиотеки компонентов VCN).
    Процедура Assert выполняет
    отладочные функции. Отладочные версии
    стандартных модулей содержат
    дополнительные режимы проверки
    корректности работы с компонентами
    Delphi.

За более сложными ошибками разработчик
должен следить из среды Delphi
самостоятельно.

Наряду с просмотром исходного текста,
для поиска логических ошибок можно
использовать и другие приемы. В том
числе инструментарий, применявшийся и
Турбо Паскале 6.07.0.
Основными инструментами отладки являются
точки контрольного останова и окно
наблюдения за переменными.

Точка останова задается с помощью опции
ViewDebug
windows
Breakpoints. Окно наблюдения
за переменными вызывается опцией
ViewDebug
Windows/Watches.
Если программа запущена из среды Delphi,
ее работу можно прервать в любой момент
опцией RunProgram
pause, или щелчком по
соответствующей кнопке панели
инструментов.

После контрольного останова в окне
наблюдения отображаются текущие значения
наблюдаемых объектов. Текущее значение
любой переменной, также можно увидеть
, если в окне редактора указать на нее
мышью (окно редактора должно быть
активным). Изменить текущее значение
переменной можно с помощью окна
Evaluate/Modify.
Прервать выполнение приложения можно
с помощью команды RunProgram
reset (ВыполнениеПрервать
выполнение).

При использовании контрольных точек
и окна наблюдения за переменными
программист может прослеживать работу
программы в пошаговом режиме с помощью
клавиш F7 (RunTrace
Into) и F8
(Run/Step Over)
(также можно применять команды Run/Trace
to Next Source
Line и Run/Run
to Cursor).

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]

  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #

Отладка программы: Классификация ошибок

Успешное завершение процесса компиляции не означает, что в программе нет ошибок. Убедиться, что программа работает правильно можно только в процессе проверки ее работоспособности, который называется тестирование.

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

Классификация ошибок.

Ошибки, которые могут быть в программе, принято делить на три группы:

  • синтаксические;
  • ошибки времени выполнения;
  • алгоритмические.

Синтаксические ошибки, их также называют ошибками времени компиляции (Compile-time error), наиболее легко устранимы. Их обнаруживает компилятор, а программисту остается только внести изменения в текст программы и выполнить повторную компиляцию.

Ошибки времени выполнения, в Delphi они называются исключениями (exception), тоже, как правило, легко устранимы. Они обычно проявляются уже при первых запусках программы и во время тестирования.

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

цию о типе (классе) ошибки. На рис. 13.1 приведен пример сообщения об ошибке, возникающей при попытке открыть несуществующий файл.

После возникновения ошибки программист может либо прервать выполнение программы, для этого надо из меню Run выбрать команду Program Reset, либо продолжить ее выполнение, например, по шагам (для этого из меню Run надо выбрать команду Step), наблюдая результат выполнения каждой инструкции.

Рис. 13.1. Сообщение об ошибке при запуске программы из Delphi 

Если программа запушена из Windows, то при возникновении ошибки на экране также появляется сообщение об ошибке, но тип ошибки (исключения) в сообщении не указывается (рис. 13.2). После щелчка на кнопке ОК программа, в которой проявилась ошибка, продолжает (если сможет) работу.

Рис. 13.2. Сообщение об ошибке при запуске программы из Windows

 

С алгоритмическими ошибками дело обстоит иначе. Компиляция программы, в которой есть алгоритмическая ошибка, завершается успешно. При пробных запусках программа ведет себя нормально, однако при анализе результата выясняется, что он неверный. Для того чтобы устранить алгоритмическую ошибку, приходится анализировать алгоритм, вручную «прокручивать» его выполнение.

Помоги проекту! Расскажи друзьям об этом сайте:

  • 60
  • 1
  • 2
  • 3
  • 4
  • 5

Типов сообщений компилятора — более двухсот. Рассмотрим перечень наиболее встречающихся сообщений класса Error

  • 0. <Что-то1> expected but <Что-то2> found. Обычно это сообщение возникает при синтаксической ошибке.Например,в случае небаланса скобок,компилятор сообщит: ‘)’ expected but ‘;’ found (вместо ожидавшейся скобки найдена запятая).

    Компилятор часто сообщает, что ‘end’ ожидается,например:x:= 5,7; здесь неуместен разделитель-запятая, а сообщается про end. (‘END’ expected but ‘,’ found)

  • 1. <Имя> is not a type identifier. Данное <Имя> не является именем типа.
  • 2. ‘;’ not allowed before ‘Else’. Перед else нельзя ставить точку с запятой
  • 3. Abstract method must be virtual or dynamic. Абстрактный метод должен быть виртуальным или динамическим.
  • 4. Ambiguous overloaded call to <Имя блока>. Компилятор не может однозначно выбрать перегружаемый блок. Измените параметр.
  • 5. Array type required. Ошибка возникает в случаях, когда в индексе элемента массива указано больше уровней, чем предусмотрено описанием, и если массив не описан. Например, после объявления двумерного массива х или простой переменной х ошибочно записывают элемент х[2,1,1] (в нем показано три измерения).
  • 6. Assignment to FOR-loop variable <Имя>. Присваивание значения параметру FOR-цикла в теле цикла.

    Например, вследствие описки дважды используется имя i в кратном цикле:

    For i:= 1 to n do For i:= 1 to m do ...
    
  • 7. Break or Continue outside of loop. Break или Continue — не в цикле.
  • 8. Cannot initialize local variables. Локальные переменные запрещено инициализировать (задавать им значения при описании).
  • 9. Cannot assign to/read a read-only/write-only property. Присвоение значения свойству read/only и чтение свойства write/only запрещены.
  • 10. Constant expression expected.В этом месте должна стоять константа или константное выражение, например константа выбора в структуре Case.
  • 11. Constant expression violates subrange bounds. Выход значения константы из диапазона. Контроль не полон. Например, «сойдет с рук» присваивание x:=3000000000, где х имеет тип integer, но начение х будет искажено.
  • 12. Constant or type identifier expected. Требуется имя типа или тип-диапазон.
  • 13. Could not compile used unit <Имя>. Компиляция присоединенного модуля <Имя> невозможна.
  • 14. Data type too large. Тип определяет структуру размером более 2 Гбайт; это слишком много.
  • 15. Declaration expected but <Что-то> found. Пропущено описание или оператор.
  • 16. Declaration of <Имя> differs from previous declarations… Данный заголовок блока не соответствует упреждающему объявлению блока.
  • 17. Default parameter <Имя> must be by-value or constant. Необязательный параметр (со значением по умолчанию) не должен вызываться по ссылке.
  • 18. Expression expected. В этом месте программы должно стоять выражение.
  • 19. Expression too complicated. Выражение излишне сложно для компиляции.
  • 20. File type not allowed here. В этом месте или в этой роли файловую переменную нельзя использовать. Например, она не может быть формальным параметром-значением.
  • 21. For loop control variable must be simple local variable. Параметр цикла должен быть простой локальной (описанной в этом же блоке) переменной.
  • 22. For loop control variable must have ordinal type. Параметр цикла должен иметь порядковый тип.Вещественный тип запрещен.
  • 23. Function needs result type. В заголовке функции надо указывать тип ее результата.
  • 24. Identifier expected but <Что-то> found. В этом месте должно стоять имя. Например, пропущено имя функции после Function.
  • 25. Identifier redeclared <Имя>.<Имя> описано повторно, но в пределах блока имя можно описать лишь раз. Проверьте, не обозначена ли локальная переменная тем же именем, что и формальный параметр блока.
  • 26. Illegal character in input file <знак>. Запретный знак, например «русская» буква, либо вы оставили скобку }, убрав открывающую скобку {.
  • 27. Illegal type in Read/Readln (Write/Writeln) statement. Элемент запрещенного типа в списке ввода/вывода.
  • 28. Incompatible types <указание типов>. Несоответствие типов по присваиванию или типов операндов одной операции. Сообщение выдается и при неверном использовании структур. Например, z — запись, ошибочно записано присваивание z:= 0 (работать надо с полями записи).
  • 29. Invalid function result type. Недопустимый тип результата функции.
  • 30. Label already defined: <Метка>. <Метка> уже помечает другой оператор.
  • 31. Left side cannot be assigned to. He может быть такой левой части в присваивании. Примеры: попытка присвоить значение файловой переменной, присвоение значения формальному параметру-константе.
  • 32. Line too long. В строке программного текста больше 255 знаков.
  • 33. Low bound exceeds high bound. Нижняя граница превышает верхнюю.
  • 34. Missing operator or semicolon.Пропуск операции (например перед скобкой) или пропуск точки с запятой. При пропуске ‘;’ маркер ошибки стоит на очередном предложении (объявлении или операторе).
  • 35. Missing parameter type. He указан тип формального параметра-значения или параметра процедурного типа.
  • 36. Not enough actual parameters. He хватает фактических параметров.
  • 37. Need to specify at least one dimension … Нужно задавать в операторе SetLength хотя бы один размер динамического массива.
  • 38. Number of elements differs from declaration. Число элементов в структурной константе не соответствует ее описанию.
  • 39. Operator not applicable to this operand type. Операция не применима к операндам данного типа. Например: ‘А’ or ‘В’; ‘Text1’* ‘Text2’.
  • 40. Order of fields in record constant differs from declaration. Порядок полей в записи-константе не соответствует описанию записи.
  • 41. Ordinal type required. Требуется порядковый тип (например, в индексе).
  • 42. Out of memory. Компилятору не хватает памяти.
  • 43. Statement expected but <Что-то> found. В этом месте должен стоять оператор. Сообщение выдается во всех случаях, когда в тело блока или секцию инициализации ошибочно помещают описание (<Что-то>). Ошибочная форма обращения к процедуре Procedure <Имя> или к функции Function <Имя> также вызывает сообщение.
  • 44. Sets may have at most 256 elements. Множество (тип Set) не может содержать более 256 элементов.
  • 45. Slice standard function only allowed as open array argument. Функцию Slice можно использовать лишь как фактический параметр
  • 46. Statement not allowed in interface part. Предложения в секции интерфейса программного модуля недопустимы.
  • 47. Syntax error in real number. Синтаксическая ошибка в записи числа вещственного типа.
  • 48. There is no overload version of <Имя> that can be called with these arguments.Не предусмотрен перегружаемый блок <Имя>, который мог бы вызываться с таким аргументом. Пример: IntToStr(x), где х – выражение вещественного типа.
  • 49. Too many actual parameters. Фактических параметров больше, чем формальных.
  • 50. Type actual and formal var parameters must be identical. Тип фактического параметра должен быть идентичен типу формального параметра-переменной.
  • 51. Type of expression must be <Тип>. Выражение должно быть указанного типа. Например,после While и Until должно стоять логическое выражение.
  • 52. Undeclared identifier: <Имя>.Не описано <Имя>. Проверьте есть ли описание в нужном месте,нет ли описок в имени. Если указано имя компонента формы, проверьте,поместили ли компонент на данную форму.
  • 53. Unexpected end of file in comment started on line <N>. Неожиданный конец файла при незавершенном комментарии, начало комментария — в строке N.
  • 54. Unit name mismatch: <Имя>. Имя модуля ошибочно.
  • 55. Unsatisfied forward or external declaration <Имя>. Отсутствует описание блока, объявление которого было дано (заголовок в интерфейсе или в описании объектного типа, либо упреждающее описание).
  • 56. Unterminate string. He закрыта апострофом строка-константа типа string.

Рассмотрим также некоторые сообщения классов warning и hint.

  • Return value of function <Имя> might be undefined. В теле функции нет присваивания ее результата.
  • Variable <Имя> might not have been initialized. Указывает имя переменой, которой не задали значения.
  • For-Loop variable <Имя> may be undefined after loop. Попытка использования значения параметра For-цикла после завершения этого цикла.
  • Text after final ‘END.’ ignored by compiler. Текст, идущий за конечной строкой модуля, игнорируется компилятором.
  • Variable <Имя> is declared but never used in <Имя блока>. Обращает внимание на переменную <Имя>, описанную,но не нашедшую применения.
  • Value assigned to <Имя> never used. Хотя бы одно значение переменной <Имя> никак не использовано.

Несколько рекомендаций

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

Не удаляйте прежний вариант кода,пока не убедитесь,что ошибка устранена. Лучше на время закомментировать код,заключив его в скобки: { код }

Компилятор не анализирует, как будет выполняться программа, поэтому выход значения индекса из диапазона выявляет только если индекс задан константным выражением. Деление на ноль вообще пропускается, кроме оператора div, в случае если делитель — константное выражение.

При компиляции Delphi программ могут возникать различные виды ошибок. Некоторые из них включают:

  1. Синтаксические ошибки: возникают, когда в коде программы есть синтаксические ошибки, такие как неправильное использование ключевых слов, неверное написание идентификаторов, отсутствие точек с запятой в конце строк и т.д.
  2. Ошибки типа: возникают, когда в программе используется неправильный тип данных или когда типы данных не совместимы друг с другом.
  3. Ошибки логики: возникают, когда в программе есть ошибки в логике, например, когда программист допустил ошибку при расчете значения или при написании условия.
  4. Ошибки времени выполнения: возникают во время выполнения программы, когда происходят ошибки, связанные с работой с памятью, вводом-выводом или другими системными функциями.
  5. Ошибки линковки: возникают, когда компилятор не может найти необходимые библиотеки или объектные файлы, необходимые для построения исполняемого файла.
  6. Ошибки взаимодействия с ОС: возникают, когда программа пытается выполнить операции, которые не разрешены операционной системой, например, когда программа пытается получить доступ к защищенной области памяти.
  7. Ошибки ввода-вывода: возникают, когда программа не может прочитать или записать данные из файла или с других устройств ввода-вывода.

Это не полный список ошибок, которые могут возникать при компиляции Delphi программ, но эти ошибки являются наиболее распространенными.

Исправление ошибок при компиляции Delphi программ зависит от типа ошибки. Вот несколько общих советов, которые могут помочь в исправлении ошибок:

  1. Внимательно прочтите сообщение об ошибке: сообщение об ошибке обычно содержит информацию о том, какая ошибка возникла и в какой части кода. Внимательное прочтение сообщения об ошибке может помочь быстро определить причину ошибки.
  2. Используйте справочник Delphi: справочник Delphi содержит информацию о ключевых словах, функциях и типах данных, которые могут быть полезны при исправлении ошибок.
  3. Используйте отладчик: отладчик может помочь определить место, где возникает ошибка, и отследить значения переменных и состояние программы в этом месте.
  4. Проверьте правильность написания кода: ошибки могут возникать из-за неправильного написания кода, так что проверьте свой код на наличие синтаксических ошибок и ошибок типа.
  5. Проверьте зависимости: если ошибка связана с линковкой, убедитесь, что все необходимые библиотеки и объектные файлы доступны и правильно подключены.
  6. Проверьте правильность использования API: если ошибка связана с взаимодействием с операционной системой, убедитесь, что вы используете API правильно и не пытаетесь выполнить операции, которые не разрешены ОС.
  7. Обратитесь к сообществу: если вы не можете исправить ошибку самостоятельно, вы можете обратиться за помощью к сообществу Delphi, например, на форумах (dropcode.ru, devhubby.com) или в группах социальных сетей.

В целом, исправление ошибок при компиляции Delphi программ зависит от специфики конкретной ошибки, поэтому важно понимать, как работает ваша программа и какие функции и библиотеки вы используете.

Okay, it’s over a year late, but I’m going to add my comment to this, as it explains why this is happening.

I had the exact same problem in a multi-threaded application with code almost identical to the snippet above and I had critical sections protecting the code.

The problem occurred most readily when one logging operation swiftly followed another. The second operation would fail for the above reason.

I thought it was anti-virus software too, but the error happened on one machine and not the other, where both had Norton 360 installed. The machine with the problem was brand new Windows 7 and the one without was Windows XP. A colleague also had the problem running the system under a virtualised Windows Vista machine with no virus checker installed.

So my question was, «why was this XP machine so different?».

For one, it wasn’t virgin, and that is the answer it seems:

Opportunistic locking and NT caching were turned off. Most (mature) Delphi developers will know that when using BDE, these are turned off in order to maintain DBF and DB file integrity in multi-user situations. These settings were not disabled on the newer machines because we no longer develop for Paradox data files!

Delayed write caching seems to leave a read/write lock on the file until the OS has done its business, which could be several milliseconds later.

So, in my case, the second log event was being blocked by the first.

Okay, I’m not suggesting that you turn off opportunistic locking + NT Caching. One of the major reasons we moved away from BDE was to avoid persuading customers to tinker with such settings. So, there are four practical solutions:

1) To retry for an acceptable period of time, as mentioned by dangph.

2) to open the file when the application loads and hold it open for the full duration of the application. Not so useful if you are running multiple instances of the application.

3) Lazily put a sleep(1) before the logging code and hope that is long enough for the lock to be released. But that risks slowing your system down if you are doing lots of logging.

or 4) Put a try…except..end around your code. But then you are probably guaranteed to miss 100% of the second messages (referring to my case).

  

Исключительные ситуации в Delphi встречаются постоянно. Исключительная ситуация это такая ситуация, в результате которой генерируется ошибка, и выполнение программы прерывается. Именно потому такая ситуация и называется исключительной. Например, деление на ноль — классический пример исключительной ситуации.

  Как в такой ситуации действует человек? Если он пытается что-то сделать, и это не получается — он идёт другим путём. Так же и компьютер, следующий программе, умеющей обрабатывать исключительные ситуации. Он не бросает выполнение программы, не виснет, а обходит исключительную ситуацию, выполняя альтернативный вариант фрагмента, в которой исключительная ситуация возникла.

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

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

  Вот как выглядит оператор контроля исключительных ситуаций:

	try
		//основные операторы фрагмента;
	except
		//альтернативный вариант фрагмента;
	end;

  Вначале производится попытка выполнить операторы секции try/except, содержащие основной вариант программы. При возникновении в каком-либо операторе этой секции исключительной ситуации остальные операторы секции пропускаются, и выполняется секция except/end. Если всё «проходит штатно», то секция except/end пропускается.

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

	try
		//операторы;
	finally
		//заключительные действия;
	end;

  Основные операторы, находящиеся в секции try, могут пройти штатно, или вызвать исключительную ситуацию. Операторы заключительных действий, находящиеся в секции finally, будут выполнены в любом случае.

  Есть ещё один способ контроля исключительных ситуаций, касающийся ошибок операций ввода-вывода.
Перед участком программы, где возможны ошибки ввода-вывода (а это, по сути, все операторы ввода-вывода), ставится директива {$I-}, заставляющая компилятор не включать в код автоконтроль ошибок ввода-вывода. Таким образом, в случае ошибки ввода или вывода программа не прерывается. В конце участка с операторами ввода-вывода ставится директива, включающая автоконтроль: {$I+}. Затем анализируется результат вызова функции IOResult. Если функция IOResult (вызывается без параметров) возвращает 0, значит ошибок ввода-вывода на данном участке не было.

Вот какой пример использования директив {$I} и функции IOResult содержит справка системы Delphi:

var
	F: file of Byte;
begin
	if OpenDialog1.Execute then //Открываем диалог выбора файла
	begin
		AssignFile(F, OpenDialog1.FileName); // Открываем файл
		{$I-} //Выключаем контроль ошибок
		Reset(F);
		{$I+} //Включаем контроль ошибок
		if IOResult = 0 then //Если ошибок нет
		begin
			//Сообщение с количеством байтов
			MessageDlg(?File size in bytes: ? + IntToStr(FileSize(F)), mtInformation, [mbOk], 0);  
			CloseFile(F); // Закрываем файл
		end
			else //Иначе
				MessageDlg(?File access error?, mtWarning, [mbOk], 0); // Сообщение об ошибке
	end;
end;

Функция IOResult досталась Delphi в наследство от Turbo Pascal. Тот же самый фрагмент можно составить и с использованием оператора try. На мой взгляд, это удобнее и проще.

При работе программы под управлением Delphi, система будет сама реагировать на исключительные ситуации, мешая работе операторов обработки исключений. Чтобы проверить их действие, можно запускать программу непосредственно, сворачивая Delphi и пользуясь ярлыком, установленном на Рабочем столе. Или можно отключить реакцию системы на исключительные ситуации, тем самым давая возможность отработать специально для этого написанным фрагментам программы — нашим операторам try/except/end. Для этого откроем пункт системного меню Delphi Tools -> Debugger Options…. В появившемся окошке нужно снять галку в чекбоксе Stop on Delphi Exceptions, расположенном на вкладке Language Exceptions. Теперь система Delphi будет предоставлять вашей программе возможность самостоятельно обрабатывать исключительные ситуации, среди которых могут быть и ситуации, возникновение которых прописано специально как удобный инструмент достижения необходимых результатов.

Удачи!
Встретимся в следующем уроке!

Классы исключительных ситуаций именуются начиная с буквы «Е», а базовый класс просто называется Exception. Этот базовый класс содержит необходимую функциональность, которую наследуют все объекты ошибок. Тут можно выделить свойство Message, в котором содержится сообщение об ошибке и функции работы с файлом помощи, через которые можно вызвать файл справки с описанием про­изошедшей ошибки.

В библиотеке VCL предопределено достаточно большое количество классов на различные типы ошибок, и все они являются наследниками Exception. Например, класс EinOutError соответствует ошибке ввода-вывода. Такие ошибки возникают при обращении к дискам.

Когда происходит ошибка, то создается объект, который является наследником класса, соответствующего типу ошибке. Так, если произошла ошибка ввода- вывода, то будет создан экземпляр класса EinOutError.

Давайте рассмотрим пример из листинга 8.10, где в блоке обработки ошибок я пытаюсь разделить число на ноль, что запрещено. Результат деления заносится в переменную t. Обратите внимание, что после этого я делаю проверку if. Эта проверка абсолютно бессмысленна и добавлена только для того, чтобы после деле­ния было хоть какое-то обращение к переменной. Если никакого обращения не бу­дет, то Delphi видит бессмысленность деления и оптимизатор не делает его.

var

t,r:Double; begin try r: =0; t:=10/r; if t>0 then exit; except
// обработка ошибки ввода-вывода

 on EinOutError do begin

ShowMessage(‘Ошибочка ввода-вывода’); end;

// обработка деления на ноль

on е:

EZeroDivide do begin .

ShoWMessage(‘Ну нельзя делить на ноль :: ‘+е.Message); end; // Иначе else

ShowMessage(‘Не понял в чем дело, но что-то произошло’);

end;

end;

В данном случае в блоке except идет два блока обработки разных типов ошибок. Чтобы проверить, не произошла ли ошибка ввода-вывода, пишем следующий блок:

on [переменная : ] класс_ошибки do begin

// Ошибка ввода-вывода end;

Если дословно перевести, что здесь написано, то это будет выглядеть так: в случае ошибки выполнить код между begin и end. Обратите внимание, что пере­менную я заключил в квадратные скобки. Это означает, что переменную заводить не обязательно, что мы и делаем при обработке ошибки ввода-вывода:

on EInOutError do begin

Shovfllessage(‘Ошибочка ввода-вывода’); end;

В случае ошибки вызывается функция showMessage, которая отображает на эк­ране окно диалога с сообщением, которое указано в качестве параметра.

А теперь посмотрим на то, как мы обрабатываем ошибку деления на ноль:

on е:EZeroDivide do begin

ShowMessage(‘Ну нельзя делить на ноль :: ‘+е.Message); end;

Ошибке деления на ноль соответствует класс EZeroDivide. Перед классом ошибки написана переменная с именем е. Через нее мы сможем узнать сообщение об ошибке, например, так е.Message.

Помимо этого, в блоке except листинга 8.10 стоит еще ключевое слово else, как при логической операции. Обратите внимание, что после end прямо перед else стоит точка с запятой, хотя мы знаем, что это ее не нужно ставить. Ненужно только для логических операций. В данном случае else используется для обработки ис­ключительных ситуаций, и операция после этого ключевого слова будет выполне­на, если до этого ошибка не была обработана. То есть если произошла ошибка, ко­торая не была обработана блоком on ошибка do, то будет выполнен код после else.

Итак, попробуйте создать новое приложение, поместить на него кнопку и по ее нажатии написать код из листинга 8.10. Запустите пример и лучше сделайте это из Delphi. Теперь попробуйте нажать на кнопку. Произойдет ошибка, и Delphi пере­хватит на себя управление, покажет строку кода, где произошла исключительная ситуация, и покажет окно диалога с сообщением, описывающим ошибку.

Осмотрев строку кода, где произошла ошибка, нажимаем клавишу <F9>, чтобы продолжить выполнение программы. И в этот момент управление будет передано нашей программе, и вы увидите сообщение, которое мы показываем с помощью функции ShowMessage В блоке except.

Если бы вы запустили программу не из Delphi, а из файлового менеджера акти­вировали исполняемый файл, созданный в Delphi, то в момент ошибки вы увидели бы только второе сообщение, которое мы отображаем с помощью функции SenMessage.

Сообщения могут генерироваться не только исполняемой средой, но и вручную. Чтобы сгенерировать свое сообщение, используется оператор raise. После этого оператора нужно указать объект ошибки. Именно объект, т. е экземпляр какого-то класса ошибки.

Давайте посмотрим, как можно вручную сгенерировать ошибку ввода-вывода. Чтобы создать новый объект этого класса, нужно вызвать метод create, а этому ме­тоду передается сообщение, которое будет отображаться, когда сработает событие.

EinOutError.Create(‘Ошибка ввода-вывода’)

Итак, конструктор create вернет нам экземпляр класса ошибки ввода-вывода. Его мы и должны указать после оператора raise:

raise EinOutError.Create(‘Ошибка ввода-вывода’);

Вы можете создать собственный класс ошибки, нарастить его возможности, как душа пожелает, и использовать его. Давайте посмотрим, как это будет выглядеть на примере. Создадим класс MyException, который будет является наследником базо­вого класса всех ошибок — Exception:

type

MyException = class(Exception) public

function GetSomeStrO:String;

end;

Это объявление типа, поэтому все это должно быть в разделе type вашего моду­ля. Помимо того что класс наследовал от базового, мы объявили еще одну функ­цию Getsomestr, которая просто возвращает строку. Не будем усложнять жизнь, а реализуем эту функцию банально — просто вернем заранее определенную строку:

function MyException.GetSomeStr: String;

begin

Result:=’Это моя строка’;

end;

Теперь поместите на форму кнопку и по ее нажатии напишите следующий код: try

raise MyException.Create(‘Тест’); except on e:MyException do

begin

ShowMessage(e.GetSomeStr);

end;

end;

В разделе try мы вручную генерируем ошибку собственного типа MyException. В разделе except мы перехватываем эту ошибку и с помощью функции ShowMessage отображаем результат функции GetSomeStr. Вот так все просто и красиво.

Помоги проекту! Расскажи друзьям об этом сайте:

Тытьяна Brabus)

0 / 0 / 0

Регистрация: 18.10.2009

Сообщений: 5

1

ООП..ошибка ввода-вывода…не понимаю что не так..

18.10.2009, 22:17. Показов 1265. Ответов 2

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

Работа с ООП…вот сама программа:

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
program Biblioteka;
 
 uses
  SysUtils,
 
  Myb in 'Myb.pas';
 
var N: TDom_Biblioteka ;
   begin
N:= TDom_Biblioteka.Create;
N.Vvod;
N. Dobavlenie;
N. Sortirovka;
N. Poisk;
N. Ydalenie_Knigi;
readln;
 end.

А вот модуль:

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
unit Myb;
 
interface
 
uses  Classes, SysUtils;
const delta = 100;
type TBibl = record
  Avtor :  string;
  Nazvanie : string;
  God :  integer; end;
 
  Bibl = array of TBibl; //массив записей
 
  TDom_Biblioteka = class
 
  Private
 
  b: Bibl;  //переменная массива Bibl
 
  Public
Constructor Create;
procedure Ydalenie_Knigi;
procedure Sortirovka;
procedure Poisk;
procedure Dobavlenie;
Procedure Vvod;
 end;
 
   Implementation
 
   Constructor TDom_Biblioteka.Create ;
begin
inherited Create;
Setlength (B, delta); end;
 
     Procedure TDom_Biblioteka.Vvod;//вводим авторов, названия,год издания
var                                    //и выводим библиотеку на экранvar
i:integer;
begin
 Setlength(b,delta);
  for i:=0 to delta-1 do begin
  writeln ('Avtor:');                                          //ВОТ ТУТ РУГАЕТСЯ.....
  readln(b[i].Avtor);//вводим автора
  writeln('Nazvanie:');
  readln(b[i].Nazvanie);//вводим название
  writeln('God:');
  readln (b[i].God);//вводим год издания
end;
  for i := 0 to delta-1 do begin  //выводим полученную библиотеку
  write(b[i].Avtor);
  write(b[i].Nazvanie);
  write(b[i].God);
  end;
end;
 
Procedure TDom_Biblioteka.Dobavlenie; //добавляем книгу в конец масива
 const delta=100;
 var
i:integer;
 
begin
Setlength(b,delta);
i := high(b);
writeln('Avtor:');
readln(b[i].Avtor);
writeln('Nazvanie:');
readln(b[i].Nazvanie);
writeln('God:');
readln(b[i].God); end;
 
   Procedure TDom_Biblioteka.Sortirovka;//сортируем по году издания
 
 var
i,t,m, min:integer;
b: Bibl;
begin
for i := 0 to delta-1  do
begin
min:=b[i].God;
t:=i;
for m := (i+1) to high(bibl) do
    if min > b[i].God then begin
    min:=b[i].God ;
    t:=m;
    b[t].God:=b[i].God;
    b[i].God:=min;
writeln(b[i].Avtor);
writeln(b[i].Nazvanie);
writeln(b[i].God); end
else writeln('Avtora ne obnaryjeno') end; end;
 
 
   Procedure TDom_Biblioteka.Poisk; //поиск книги по автору
var
i:integer;
m:string;
b: Bibl;
begin
writeln('Vvedite avtora');
readln(m);
 for i := 0 to delta-1 do
  begin
  if m=b[i].Avtor then
   begin
   writeln (b[i].Avtor);
   writeln(b[i].Nazvanie);
   writeln(b[i].God);
   end
  else writeln('Avtora ne obnarujeno')
 end;
end;
 
  Procedure TDom_Biblioteka.Ydalenie_knigi;//удаляем книгу из массива
var
i, last:integer;
k:string;
b: Bibl;
begin
writeln('Vvedite nazvanie knigi, kotoryu xotite ydalit');
readln(k);
for i := 0 to delta-1 do begin
if k = b[i].Nazvanie then
writeln (b[i].Avtor);
writeln(b[i].Nazvanie);
writeln(b[i].God);
 end;
last:=high(B);
If i < last then begin b[i]:=b[i+1];
Setlength (b, last-1);
end
else writeln ('Knigi ne obnarujeno')   end;
 
 end.

там где Procedure TDom_Biblioteka.Vvod; когда вводим автора writeln (‘Avtor:’); — ругается((( вобще не понимаю что ему не нравится…

0

schdub

Эксперт С++

3068 / 1406 / 425

Регистрация: 19.01.2009

Сообщений: 3,847

19.10.2009, 07:00

2

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

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
program Biblioteka;
 
{$APPTYPE CONSOLE}
 
uses
  SysUtils,
  Myb in 'Myb.pas';
 
var N: TDom_Biblioteka;
 
begin
  N:= TDom_Biblioteka.Create;
  N.Vvod;
  N.Dobavlenie;
  N.Sortirovka;
  N.Poisk;
  N.Ydalenie_Knigi;
  readln;
end.

2

0 / 0 / 0

Регистрация: 18.10.2009

Сообщений: 5

20.10.2009, 16:06

 [ТС]

3

хахах =))) блин…какая глупая ошибка..а я 2 недели голову ломала =))))) СПАСИБО!=)))))

0

Понравилась статья? Поделить с друзьями:
  • Синтаксические нормы типы синтаксических ошибок
  • Синтаксическая ошибка это пример
  • Синтаксические ошибки список
  • Синтаксические нормы типичные синтаксические ошибки
  • Синтаксическая ошибка это когда