Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
УМК ПП1 (C++ БД).doc
Скачиваний:
3
Добавлен:
01.03.2025
Размер:
5.01 Mб
Скачать

Раздел 2. Ввод данных

При изучении данного раздела вы должны проработать следующие темы:

2.1. Организация надежного ввода.

2.2. Обработка строк.

2.3. Средства группирования компонентов.

Для проверки усвоения материала Вам предстоит ответить на вопросы для самопроверки, приведённые в конце раздела, а затем выполнить лабораторные работы №1.2 и №1.3 и тренировочный тест №2. Изучение раздела заканчивается контролем знаний: необходимо ответить на вопросы контрольного теста №2. Максимальное количество баллов, которое вы можете получить по данному разделу, равно 7.5 (1.5 баллов за тестирование и ещё 6 баллов за лабораторные работы).

2.1. Организация надежного ввода

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

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

программа никогда не «зависает», независимо от ввода любых данных;

программа не реагирует на недопустимые манипуляции пользователя;

программа индицирует ошибку, предупреждающую о недопустимых символах или их сочетаниях;

минимизировано количество ударов по клавишам, необходимых для ввода нужных данных.

Достичь выполнения таких требований очень непросто, так как это сопряжено с привлечением дополнительных средств интерфейса и разработкой алгоритмов анализа вводимых данных. Для программ уровня студенческих курсовых проектов можно предположить, что трудоёмкость построения программы, хорошо защищённой от ошибок ввода, в ДВА РАЗА выше, чем простой программы, где защита обеспечивается только средствами интерфейса.

Существует несколько приёмов решения проблемы защиты ввода:

  1. использовать компоненты ввода с масками, разрешающими ввод только разрешённых символов (MaskEdit);

  2. применять алгоритмические методы анализа допустимости и правильности введённых данных;

  3. использовать системные операторы try для попытки анализа правильности введённого данного и обхождения исключительной ситуации в случае ввода недопустимых значений;

  4. применять защиту окон ввода на программно-аппаратном уровне, используя собственный обработчик прерываний события KeyPressed.

  5. скрывать на интерфейсе окна ввода в таком контексте, когда ввод запрещён, нежелателен или может привести к двусмысленностям.

Использование компонентов ввода с масками (типа MaskEdit) является самым простым и распространённым, но не самым эффективным методом защиты. Его освоение предполагается путем самостоятельной работы.

Алгоритмические методы

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

  • состоящие только из русских букв?

  • являющиеся только одним словом без пробелов?

  • состоящие из нескольких отдельных слов?

  • содержащие в качестве символов цифры?

  • допускающие не более трех согласных подряд?

  • допускающие не более двух гласных подряд?

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

Обработка исключений

Если во время выполнения программы (на фазе RunTime) ПК сталкивается с ситуацией, когда он не может выполнить требующегося от него действия, операционная система генерирует код этой исключительной ситуации. Стандартная реакция на исключение такова:

  • на экран выдаётся сообщение на английском языке о ситуации, приведшей к аварийному завершению (рис. 1);

  • выполнение программы прекращается (иногда при этом машина «зависает», что может потребовать её перезагрузки).

Рис. 1. Стандартная реакция на исключительную ситуацию

Общие сведения об операторе try изложены в [1 и 4, с. 107-109]. Использование операторов try достаточно эффективно и может предотвратить многочисленные аварийные ситуации. Однако как первый, так и второй способы защиты направлены на исправление возможных ошибок, а не на их предотвращение, тогда как всегда лучше ПРЕДОТВРАТИТЬ появление ошибки, а не ИСПРАВИТЬ её последствия.

Защита окна ввода с использованием собственного обработчика прерываний события KeyPressed

Сущность этого метода в том, что анализируется символ, введённый с клавиатуры до того, как он попадает в область программы. Рассмотрим аппаратную схему организации ввода в стандартное окно типа Edit (рис. 2).

Рис. 2. Стандартная схема ввода символа с клавиатуры в окно Edit1

Исходное состояние: курсор установлен на окне Edit1. При нажатии на клавишу, предположим, A (лат), клавиатура генерирует сигнал, который интерпретируется как ANSI-код этой буквы, то есть 65. Этот код присваивается глобальной системной переменной, имеющей наименование KEY. Системной называется переменная, принадлежащая области операционной системы; глобальная переменная доступна не только для системных программ, но и для приложений пользователя.

В нормальном режиме переменная KEY направляется на вход знакогенератора. Это электронная управляющая схема, управляющая дисплеем таким образом, что при приходе ANSI-кода (в нашем примере - 65) на экране в области Edit1 будет прорисовано изображение буквы «A», а код KEY (='A') будет записан в свойство Edit1->Text.

Как известно [4,с.45] , в ANSI-таблице коды символов имеют значение от 32 до 255, а управляющие коды – от 0 до 31. Особую роль играет код 0: он блокирует дальнейшее движение переменной KEY. Это значит, что если на вход знакогенератора пришла системная переменная KEY=0, то никакого изменения экрана не произойдет и в свойство Edit1->Text ничего записано не будет.

На знании логики обработки системной переменной KEY и основан наилучший способ защиты окна ввода от недопустимых символов (рис. 3) .

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

знакогенератор

недопустим

допустим

Рис. 3. Алгоритм защиты окна от ввода недопустимх символов

Пример реализации алгоритма, пропускающего в окно Edit1 только русские буквы от «А» до «я», приведён на рис. 4.

void __fastcall TForm1::Edit1KeyPress(TObject *Sender, char &Key)

{ if ((Key>='А')&&(Key<='я'))

return;

else Key=0;

}

Рис. 4. Алгоритм, пропускающий в окно ввода только русские буквы

Обратите внимание на следующие обстоятельства.

  • Обработчик построен не на обычном событии OnClic, а на событии OnKeyPressed, которое наступает, когда курсор установлен в области окна Edit1 и нажата любая клавиша пульта.

  • В списке параметров построенной Builder-ом процедуры Edit1KeyPress тип системной переменной Key указан как char (character). Такая переменная обладает дуальной природой, то есть её можно интерпретировать как символ или как число типа byte [4,c.41].

  • В списке параметров процедуры Edit1KeyPress переменной Key предшествует указатель &.

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

Теперь рассмотрим текст алгоритма. Если входная переменная Key принадлежит русскому алфавиту, то есть условие

if ((Key>='А')&&(Key<='я'))

имеет значение true, то выполняется оператор return , обеспечивающий возврат в операционную систему. При этом значение Key не изменилось, значит, оно содержит ANSI-код нажатой клавиши. Этот код направляется к знакогенератору, изображение буквы прорисовывается на экране, сам код добавляется к Edit1->Text.

Если же входная переменная Key не принадлежит русскому алфавиту, то есть условие

if ((Key>='А')&&(Key<='я'))

имеет значение false, то оператор return пропускается, и выпоняется присваивание

Key=0.

Заметьте, что в правой части записан не символ ноль, а число 0, что возможно из-за двойственной природы переменной char Key. Тогда переменная Кеу из носителя символа превращается в управляющий код, который передаётся операционной системе и блокирует знакогенератор.

Подробнее защита окна ввода аналогичными приёмами рассматривается в лабораторной работе №1.1, часть 3.

Управление видимостью разрешенных окон ввода

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