Как сделать проверку на ввод чисел в c

Добавил пользователь Валентин П.
Обновлено: 04.10.2024

Будем жить, Маэстро.

Конфигурация компьютера
Процессор: Intel Pentium 4 Socket 478 2.26 Ghz/512/533 BOX
Материнская плата: ABIT IS7-E2 i865PE+ICH5, S-478 VC 6ch SB Lan ATX 2 DDR 400
Память: PQI DDR 512 Mb, 400 Mhz
HDD: SAMSUNG HD103SJ (1000 Гб, SATA)
Видеокарта: AGP ATI Radeon X1550 256/128 DDR2 (Palit)
Звук: Интегрированный звук
Блок питания: ATX Midle Tower CODEGEN 6205-C9 P4, 300W, 27 Ноября 2004 г.
CD/DVD: LG DVD-RW, GSA-H30N RBBB (SATA)
Монитор: Samsung SyncMaster 223BW(Digital) [NoDB] (HMEQ201792) [21.6" LCD-TFT Монитор]
ОС: Windows XP Professional (SP-3) Russian. Special Edition XP
Прочее: Borland C++ Builder 6.0 Enterprise Suite и CodeGear C++ Builder 2009

Куда запретить? Если компонет Edit в Borland C++ Builder то лучше использовать MaskEdit
Вопрос бедный, для каких целей? Где это нужно?

Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Drongo, автор ищет альтернативу обычной консольной функции getch().
DENoszone, в почему бы не дать юзеру ввести всё символы, что он желает, а потом выбрать из этой строчки только цифры?

imho на чистом си (переносимом) изобразить не получится - надо привязываться к платформе - использовать winapi или прерывание dos.

Admiral, эээ как.
ну это и есть то что я хочу. только если там имеются буквы то сказать досвидания и введите заново.
как осуществить?

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

Теперь ясно, что требовалось: названия темы предусматривает на любой введённый символ, если он не цифра, не реагировать, даже не отображать. Сам не задавался такой целью, но скорей всего это реализуется средствами платформы, как указал Busla.
Что б сделать повторы можно, например использовать цикл: while или repeat. Из этих двух предложенных repeat будет более логично, перевод же "повторить", всё же оно должно хотя бы раз спросить.

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

Элемент управления MaskedTextBox

Если требуется, чтобы пользователи вводили данные в четко определенном формате, например номер телефона или артикул, это можно сделать быстро и с минимальным количеством кода с помощью элемента управления MaskedTextBox. Маска — это строка, состоящая из символов языка маскирования, которые указывают, какие символы можно вводить в каждой заданной позиции в текстовом поле. Элемент управления отображает набор запросов пользователю. Если пользователь вводит неправильное значение, например, вводит букву, когда требуется цифра, элемент управления автоматически отклоняет введенные данные.

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

Проверка на основе событий

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

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

Если почтовый индекс должен быть допустимым почтовым индексом США, можно вызвать веб-службу почтовых индексов для проверки данных, введенных пользователем.

Событие Validating предоставляется объектом типа CancelEventArgs. Если вы определили, что данные элемента управления недопустимы, отмените событие Validating, задав свойству Cancel этого объекта значение true . Если свойство Cancel не задано, Windows Forms будет считать, что проверка для этого элемента управления прошла удачно, и порождает событие Validated.

Пример кода, который проверяет адрес электронной почты в TextBox, см. в справочнике по событию Validating.

Управляемые событиями элементы управления с привязкой к данным

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

При использовании привязки данные в элементе управления синхронизируются с источником данных во время выполнения события Validating. Если отменить событие Validating, данные не будут синхронизированы с источником данных.

Если после события Validating выполняется пользовательская проверка, это не повлияет на привязку данных. Например, если в событии Validated имеется код, который пытается отменить привязку данных, привязка данных все равно будет выполняться. В этом случае для выполнения проверки в событии Validated измените значения свойства элемента управления Binding.DataSourceUpdateMode с DataSourceUpdateMode.OnValidation на DataSourceUpdateMode.Never и добавьте your-control.DataBindings["field-name"].WriteValue() в код проверки.

Явная и неявная проверка

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

Неявная проверка

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

Если вы хотите использовать неявную проверку для элемента управления, необходимо задать его свойству AutoValidate значение EnablePreventFocusChange или EnableAllowFocusChange. При отмене события Validating поведение элемента управления будет определяться значением, назначенным свойству AutoValidate. Если вы установили значение EnablePreventFocusChange, отмена события приведет к возникновению события Validated. Фокус поля ввода будет оставаться на текущем элементе управления до тех пор, пока пользователь не изменит данные на допустимый формат. Если вы установили значение EnableAllowFocusChange, событие Validated не произойдет при отмене события, но фокус по-прежнему будет переходить к следующему элементу управления.

Присвоение значения Disable свойству AutoValidate полностью отключает неявную проверку. Тогда для проверки элемента управления необходимо использовать явную проверку.

Явная проверка

При явной проверке данные проверяются за один раз. Вы можете проверить данные в ответ на действие пользователя, например нажатие кнопки Сохранить или ссылки Далее. При возникновении действия пользователя можно активировать явную проверку одним из следующих способов:

  • вызов метода Validate, чтобы проверить последний элемент управления, который потерял фокус;
  • вызов метода ValidateChildren, чтобы проверить все дочерние элементы управления в форме или контейнере;
  • вызов пользовательского метода для проверки данных в элементах управления вручную.

Поведение по умолчанию неявной проверки для элементов управления

Различные элементы управления Windows Forms имеют разные значения по умолчанию свойства AutoValidate. В следующей таблице показаны наиболее распространенные элементы управления и их значения по умолчанию.

Control Поведение проверки по умолчанию
ContainerControl Inherit
Form EnableAllowFocusChange
PropertyGrid Свойство не предоставлено в Visual Studio
ToolStripContainer Свойство не предоставлено в Visual Studio
SplitContainer Inherit
UserControl EnableAllowFocusChange

Закрытие формы и переопределение проверки

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

  • нажатием кнопки Закрыть;
  • выбором пункта меню Система >Закрыть;
  • вызовом метода Close программным способом.

Однако в некоторых случаях может потребоваться разрешить пользователю закрывать форму независимо от того, являются ли значения в элементах управления допустимыми. Можно переопределить проверку и закрыть форму, которая все еще содержит недопустимые данные, создав обработчик для события FormClosing формы. В событии задайте для свойства Cancel значение false . Это приведет к принудительному закрытию формы. Дополнительные сведения и пример см. в разделе Form.FormClosing.

Если принудительно закрыть форму таким образом, все данные в элементах управления формы, которые еще не были сохранены, теряются. Кроме того, модальные формы не проверяют содержимое элементов управления при их закрытии. Вы по-прежнему можете использовать проверку элемента управления для блокировки фокуса на элементе управления, но вам не нужно беспокоиться о поведении, связанном с закрытием формы.

Я новичок в C ++, и у меня есть функция, в которой я хочу, чтобы пользователь ввел double значение. Как мне обеспечить, чтобы введенное значение имело правильный тип данных? Кроме того, как будет обработана ошибка? На данный момент это все что у меня есть:

Я использую `try <> catch () <>, но я не думаю, что это правильное решение для этой проблемы. Любая помощь будет оценена.

Решение

Если ostream& operator>>(ostream& , T&) не удается извлечь отформатированные данные (такие как целое число, двойное число, число с плавающей запятой, …), stream.fail() будет правдой и, таким образом, !stream оценит как истину тоже.

Так что вы можете использовать

Это важно ignore остальная часть линии, так как operator>> больше не будет извлекать данные из потока, так как они в неправильном формате. Так что если вы удалите

Ваш цикл никогда не закончится, так как вход не очищен от стандартного ввода.

    ( cin.ignore ) ( cin.fail() ) (используется для максимального количества игнорируемых символов, определенного в
  • ).

Другие решения

Вам нужно прочитать всю строку, используя std::getline а также std::string , Это способ полностью проверить, что вся строка имеет правильный тип данных:

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

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

В работе над этой статьей, я использовал Microsoft Visual Studio 2008 Standard с установленным SP1.

Для наших экспериментов, возьмем очень простой код:

using namespace std;

int main()
<
int a, b;
// Вводим первое число
cout "Enter \"A\": " ;
cin >> a;
cout "You have entered: "

// Вводим второе число
cout "Enter \"B\": " ;
cin >> b;
cout "You have entered: "

// Do something with a and b

cout "Thanks a lot. Press any key for exit." while (!_kbhit());
>

Для начала, посмотрим как выглядит корректная работа программы.

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

Как вы видите, программа естественно сработала не правильно.

cout "Incorrect input."

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

Казалось бы, что все, но нет. Давайте разберемся, почему:

2 Что хранится во входном потоке.

Ответ на этот вопрос прост. В Visual Studio, этим значением, инициализируются неинициализированные локальные переменные. Это если компилировать программу в Debug-режиме. А в Release сборке, числа будут случайными.

Как это происходит? Когда пользователь вводит текст, то естественно, строчка “ cin >> a ;” выполняется с ошибкой, потому, что ожидается число. Естественно, в переменную a ничего не записывается и происходит ее неявная инициализация.

Для того, чтобы в переменной, при не правильном вводе хранилось какое-то число(отличное от
-858993460), то можно либо в блоке, где мы проверяем входной поток на ошибки, добавить явную инициализацию ( “a = -1;” ), либо инициализировать переменную при объявлении. Таким образом в переменной уже будет храниться число и оно не измениться при некорректном вводе.

Ну, а это самый просто вопрос. Что пользователь вводил, то и храниться.

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

Здравствуйте, maksqwe, Вы писали:

M>. Прога у меня считывает вводимую инфу, предположим какое-либо число (int), как сделать проверку введенных символов, на факт присутствия в них символов не относящихся к цифрам? Просто если ввести буквы, а прога считывает в интовскю переменную, то она вылетает.

В некоторых случаях можно так:

On Sun, 24 Dec 2006 16:42:35 +0500, maksqwe wrote:

> Прога — консолька, пишу на Visual Studio 2005.
> Собственно столкнулся с такой неприятной неприятностью. Прога у меня
> считывает вводимую инфу, предположим какое-либо число (int), как
> сделать проверку введенных символов, на факт присутствия в них символов
> не относящихся к цифрам? Просто если ввести буквы, а прога считывает в
> интовскю переменную, то она вылетает.

string s;
cin >> s;
int i;
int err = sscanf(s, "%d", &i);

Я только начинающий программер. Потому не надо писать типа ". вот ламо. rtfm. " Я лишь прошу консультации.

Прога — консолька, пишу на Visual Studio 2005.
Собственно столкнулся с такой неприятной неприятностью. Прога у меня считывает вводимую инфу, предположим какое-либо число (int), как сделать проверку введенных символов, на факт присутствия в них символов не относящихся к цифрам? Просто если ввести буквы, а прога считывает в интовскю переменную, то она вылетает.

Прошу помочь!! Буду премного благодарен!

Здравствуйте, maksqwe, Вы писали:
Вот вам костыль из моей далекой молодости
Вообще — он ужасен, но работает(сделан специально под виндовый cmd)
см. коментарии.

пример использования кривого костыля:

Здравствуйте, maksqwe, Вы писали:

M>Я только начинающий программер. Потому не надо писать типа ". вот ламо. rtfm. " Я лишь прошу консультации.

M>Прога — консолька, пишу на Visual Studio 2005.
M>Собственно столкнулся с такой неприятной неприятностью. Прога у меня считывает вводимую инфу, предположим какое-либо число (int), как сделать проверку введенных символов, на факт присутствия в них символов не относящихся к цифрам? Просто если ввести буквы, а прога считывает в интовскю переменную, то она вылетает.

M>Прошу помочь!! Буду премного благодарен!
Для этого нужно написать собственную функцию посимвольного ввода с проверкой на легальность символов.

Здравствуйте, maksqwe, Вы писали:

M>Прога — консолька, пишу на Visual Studio 2005.
M>Собственно столкнулся с такой неприятной неприятностью. Прога у меня считывает вводимую инфу, предположим какое-либо число (int), как сделать проверку введенных символов, на факт присутствия в них символов не относящихся к цифрам? Просто если ввести буквы, а прога считывает в интовскю переменную, то она вылетает.

2 All: я понимаю, что Boost — то еще развлечение для начинающего, но надо начинать с лучшего, верно?

P. S. Это всё из предположения, что язык — C++.

RO>// если вводим из потока (stream >> s), то можно и сразу проверять — см. совет г-на Лаптева выше.

I>В некоторых случаях можно так:

I>

После чего бесконечно повторяется следующая функция. Как сделать что бы этого не происходило.

Здравствуйте, maksqwe, Вы писали:

I>>В некоторых случаях можно так:

I>>

M>После чего бесконечно повторяется следующая функция. Как сделать что бы этого не происходило.
вот так — читай сюда:

Состояния потока
Каждый поток (и стандартные в том числе) в каждый момент времени находится в некотором состоянии. Эти состояния имеют названия good, bad, fail и eof (end-of-file). Сами состояния определены в классе ios_base как целые статические константы. Эти константы называют флагами состояния потока [1-27.4.2.1.3].

Значения флагов зависят от реализации (показанные значения флагам присвоены в системе C++ Builder 6), однако имена определены в стандарте, поэтому именно так флаги состояния называются во всех без исключения системах. В программе имена флагов состояния нужно записывать с префиксом, например

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

В базовом классе ios_base определено поле

ПРИМЕЧАНИЕ
Такое имя поле имеет в системе Borland C++ Builder 6. В другой реализации имя поля может быть другим.
В этом поле сохраняются флаги состояния во время работы программы. Это поле мы можем прочитать методом

Установить любой флаг можно методом

Для установки нескольких флагов, естественно, нужно воспользоваться битовыми операциями, например

Система ввода/вывода С++ предоставляет несколько методов, с помощью которых мы всегда можем узнать состояние потока:

Если после выполнения некоторой операции поток находится в состоянии good, то это хорошая ситуация: во время предыдущей операции не произошло никаких непредвиденных событий и может быть выполнена следующая операции ввода/вывода. В остальных случаях следующая операция выполнена не будет.
Состояние fail и состояние bad являются состояниями ошибки потока. Если поток находится в одном из этих состояний, то операции обмена не выполняются. Состояние bad включает в себя состояние fail: когда поток находится в состоянии bad, он находится и в состоянии fail; обратное неверно.
Если поток находится в состоянии fail, то операция ввода/вывода завершилась неудачно, однако поток не испорчен и никакие символы не потеряны. Обычно это состояние устанавливается при ошибках форматирования в процессе чтения — например, программа пытается прочитать целое число, а первый же символ является недопустимым (буква или знак операции). Поток из состояния fail мы можем вернуть в нормальное состояние с помощью метода clear(), например

После этого можно выполнять операции обмена — опять до очередной ошибки. Метод clear() перегружен и позволяет не только сбросить, но и затем установить нужные флаги состояния. Прототип этого метода

Состояние bad – это более тяжелое состояние. Флаг badbit указывает на неработоспособность потока данных или потерю данных. Когда поток в состоянии bad, ни в чем нельзя быть уверенным, поэтому в таких случаях лучше завершать выполнение программы.
Состояние eof может возникнуть только при операции чтения. Для стандартного потока ввода это состояние возникает при вводе комбинации клавиш + . Для файлов это состояние устанавливается при первой попытке чтения после последнего байта файла. При этом поток тоже переводится в состояние fail.
Состояние потока и логические условия
Состояние потока можно проверять непосредственно в условиях if и while. Например, ввод массива целых значений можно выполнять в цикле таким образом

Символ ‘e’после цифры 5 не является допустимым для целого числа, поэтому ограничивает ввод.
В условиях можно задавать и явный вызов методов. Например, мы хотим посчитать количество символов ‘\n’, которым оканчиваются вводимые строки. Это можно сделать, используя метод get():

Константа EOF помещается в ch при нажатии комбинации + .
В библиотеке реализована логическая операция operator!, с помощью которой можно проверить аварийное состояние потока, например

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

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

Однако тут возможны сюрпризы. По умолчанию ограничителем строки является символ ‘\n’, который записан в конце каждой строки. В данном случае при считывании последней строки ситуации конца файла не возникает — она возникает только при попытке ввода за концом файла. Поэтому цикл выполнится лишний раз и на экране дважды появится последняя строка.
Правильная последовательность операторов может быть такой

Если ширина поля ввода установлена (то есть, не равна нулю), то объявляется строка для ввода и ввод выполняется в нее. Затем этой строкой инициализируется строковый поток. Обратите внимание на то, что ввод из строкового потока проверяется на корректность и в случае ошибки устанавливается флаг failbit для входного потока-параметра.
Использовать эту функцию можно так:

Потоки и исключения
По умолчанию при ошибках ввода/вывода исключения не генерируются. Однако можно указать, при установке каких флагов состояния должно генерироваться исключение. В состав класса basic_ios [1-27.4.4] входит метод exceptions(), который и позволяет это сделать. Прототип метода следующий

Задать генерацию исключения при установке флага ios::badbit можно так:

Флаги, как обычно, можно комбинировать, например

Исключения будут генерироваться не только во время операций ввода/вывода, но и при установке флагов методами clear() и setstate().
Если аргумент равен 0 или ios::goodbit, исключения генерироваться не будут.
Вызов без аргумента возвращает текущие флаги, при установке которых генерируется исключение, например

Если возвращается goodbit, исключения не генерируются.
Генерируемые исключения являются объектами класса ios_base::failure [1 27.4.2.1.1], который является наследником класса exception (см. главу 4). Класс ios_base::failure имеет следующую структуру:

Как видите, сложного ничего нет.

Здравствуйте, maksqwe, Вы писали:

M>Я только начинающий программер. Потому не надо писать типа ". вот ламо. rtfm. " Я лишь прошу консультации.

M>Прога — консолька, пишу на Visual Studio 2005.
M>Собственно столкнулся с такой неприятной неприятностью. Прога у меня считывает вводимую инфу, предположим какое-либо число (int), как сделать проверку введенных символов, на факт присутствия в них символов не относящихся к цифрам? Просто если ввести буквы, а прога считывает в интовскю переменную, то она вылетает.

M>Прошу помочь!! Буду премного благодарен!

для этого нужно просто считывать не в числовую переменную а в строковую. после -- конвертировать ее в числовое значение -- ошибки не будет. если человек введёт "вася", то оно просто конвертирует его безошибочно в значение 0.

более сложный вариант: -- читать посимвольно и пропускать только символы от "0" до "9".

Здравствуйте, Megabyte, Вы писали:

M>sscanf(s, "%d", &i);

Или istringstream(s) >> i.

Здравствуйте, maksqwe, Вы писали:

M>Прога — консолька, пишу на Visual Studio 2005.
M>Собственно столкнулся с такой неприятной неприятностью. Прога у меня считывает вводимую инфу, предположим какое-либо число (int), как сделать проверку введенных символов, на факт присутствия в них символов не относящихся к цифрам?

Читайте также: