Как сделать проверку вводимых значений в c

Добавил пользователь Евгений Кузнецов
Обновлено: 04.10.2024

В этом руководстве мы узнаем о функции isdigit() C++ с помощью примеров.

Функция isdigit() в С++ проверяет, является ли данный символ цифрой или нет.

Синтаксис

Синтаксис функции isdigit():

Здесь ch – это символ, который мы хотим проверить.

Параметры

Функция принимает следующие параметры:

  • ch – проверяемый символ, приведенный к типу int или EOF

Возвращаемое значение

Функция isdigit() возвращает:

  • ненулевое целочисленное значение (истина), если ch – цифра
  • целое число ноль (ложь), если ch не является цифрой

Прототип isdigit(), как определено в заголовочном файле cctype:

Как мы видим, символьный параметр ch на самом деле имеет тип int. Это означает, что функция isdigit() проверяет значение ASCII символа.

Поведение isdigit() не определено, если:

  • значение ch не может быть представлено как unsigned char, или
  • значение ch не равно EOF.

Пример: C ++ isdigit()

Здесь мы создали строку C str . Затем мы напечатали только цифры в строке, используя цикл for. Цикл выполняется от i = 0 до i = strlen (str) – 1.

Другими словами, цикл проходит по всей строке, поскольку strlen() дает длину str .

На каждой итерации цикла мы используем функцию isdigit(), чтобы проверить, является ли строковый элемент str [i] цифрой или нет. Результат сохраняется в проверочной переменной.

Если проверка возвращает ненулевое значение, мы печатаем строковый элемент.

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

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

Решение

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

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

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

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

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

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

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

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

Я хотел бы знать, как ограничить входное значение знаковыми десятичными знаками, используя std::cin .

Если переменная поддержки cin - это число, а строка не является числом, возвращаемое значение равно false, поэтому вам нужен цикл:

оператор cin >> работает, читая по одному символу за раз, пока он не попадет в пробел. Это будет хлебать всю строку -1a2.0 , что, очевидно, не является числом, поэтому операция завершается неудачей. Похоже, у вас на самом деле есть три поля: -1, a и 2.0. Если вы разделите данные пробелами, cin сможет прочитать каждый из них без проблем. Просто не забудьте прочитать char для второго поля.

объединение методов из верхнего ответа здесь и этой веб-сайт, я получаю

введите целое число: a
Неверный ввод.
Введите целое число: 2b
Неверный ввод.
Введите целое число: 3
Вы ввели: 3.

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

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

теперь я думаю, что getline() функция (не метод с тем же именем на std::istream ) и strtol() функция из include cstdlib является единственным предсказуемым последовательным решением этой проблемы. Я был бы признателен, если бы кто-нибудь доказал, что я не прав. Вот что-то вроде того, что я использовать:

должен прочитать ваш подписанный "десятичный" штраф.

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

Здравствуйте, 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), как сделать проверку введенных символов, на факт присутствия в них символов не относящихся к цифрам?

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