Всем привет.
Послушала я про то, что необходимо портфолио и решила что-то придумать (мои программы не перевернут этот мир, но с чего-то необходимо начинать).
Так вот, решила я сделать программку, в которой пользователь должен ввести число и при любом раскладе он не выиграет. Необходимо ему ввести число от 1 до 10 включительно (только целочисленные значения). Если пользователь вводит число целочисленное, не входящее в указанный промежуток, то программа сообщает ему об ошибке и просит ввести число, отвечающее требованиям. Здесь все хорошо, но трудности у меня возникли с тем, что если пользователь введет вещественное число либо букву/символ (в общем все, что не является целочисленным числом), то цикл просто начинает бесконечно прокручиваться.
Сам код:
#include <iostream>
#include <string>
#include <time.h>
#include <cctype>
using namespace std;
int main()
{
srand(time(NULL));
int a;
const int SIZE = 10;
int isdigit( int a );
int arr[SIZE];
cout<<"Input number from 1 to 10:t";
cin>>a;
while (isdigit(0))
{cout<<"Error!!! Please input number from 1 to 10!"<<endl<<endl;
cout<<"Input number from 1 to 10:t";
cin>>a; }
while (a<1 ||a>10)
{ cout<<"nError!!! Please input number from 1 to 10!"<<endl<<endl;
cout<<"Input number from 1 to 10:t";
cin>>a;}
cout<<"nYour number is t"<<a<<endl<<endl;
for (int i = 0; i<SIZE;)
{
arr[i] = 1+ rand()%10;
if (a!=arr[i]){
cout<< arr[i]<<"t";
i++;
}
else continue;
}
cout<<"nnSorry, but you lose :(nnTry again, maybe you'll win";
}
Подскажите, пожалуйста, как можно выйти из цикла в случае ввода вещественного числа/символа/буквы и предложить пользователю заново ввести число.
Спасибо!
Не получается реализовать проверку на дурака в c++, работает только частично, нужно чтобы при вводе данных, если не число, выводилось сообщение «Повторите попытку» и заново ввод.
int workIntUserInput( int inputInt ){
while(true){
wcin >> inputInt;
if( !wcin ){
wcout << L"nОшибка! Некорректные данные!nn";
wcin.clear();
while( wcin.get() != 'n' );
} else break;
}
return inputInt;
}
Принимает числа с запятыми, точками, минус буква, минус ноль.
Проверка должна работать при любом бреде — выводить повторный ввод, если же проходит проверку — вернуть значения.
Также были другие попытки написания функции, но они абсолютно не читабельные (пытался реализовать при помощи isdigit, переводил в стринг — по символьна).
Kromster
13.5k12 золотых знаков43 серебряных знака72 бронзовых знака
задан 23 апр 2019 в 22:43
2
Ну вот, когда-то подхалтуривал —
int inputInt(const char * prompt, int m = INT_MIN, int M = INT_MAX)
{
int N;
for (;;) {
std::cout << prompt << " (целое от " << m << " до " << M << "): " << std::flush;
if ((std::cin >> N).good() && (m <= N) && (N <= M)) return N;
if (std::cin.fail()) {
std::cin.clear();
std::cout << "Неверный ввод, повторите.n";
} else {
std::cout << "Число вне допустимого диапазона значений. Повторите ввод.n";
}
cin.ignore(std::numeric_limits<std::streamsize>::max(), 'n');
}
}
a = inputInt("Введите размер массива",1,10);
Для широких символов, думаю, сами переправите?…
ответ дан 24 апр 2019 в 3:43
HarryHarry
215k15 золотых знаков117 серебряных знаков228 бронзовых знаков
0 / 0 / 0
Регистрация: 10.09.2020
Сообщений: 20
1
Переместить пользователя снова на ввод числа, если он вводит не число
18.10.2020, 16:03. Показов 2970. Ответов 6
Не совсем могу додуматься до того, как вернуть пользователя на ввод числа, если он вводит в а, b или c не число, а какой-нибудь символ (На данный момент, если пользователь вводит не число, то программа выдает format exception).
Понимаю, что это скорее всего можно реализовать через if, но не могу додуматься как.
C# | ||
|
Не кидайтесь палками за колхоз в коде, шарп начал изучать 2 часа назад
0
Содержание
- Пример исключения в C#
- Блок try…catch…finally
- Перехват и обработка исключений в блоке catch
- Логические операции и обработка исключений в C#
- Итого
уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
При разработке программного обеспечения мало составить и реализовать какой-либо алгоритм, важно также предусмотреть всевозможные непредвиденные ситуации при работе вашей программы и, в случае необходимости отловить и обработать исключения, которые могут возникнуть. Например, вы решили разработать программу-клиент для работы с блогом, которая позволяет публиковать статьи, модерировать комментарии и выполнять прочую полезную работу. Как бы вы не старались сделать свое приложение работоспособным, неизбежно, при работе с программой пользователь может столкнуться с такими проблемами: сайт недоступен (например, в результате ошибки сервера 5хх), не возможно соединиться с базой данных и так далее. В любом из этих случаев, без должной обработки исключений, ваша программа будет аварийно завершать работу и пугать пользователей сообщениями об ошибках. Сегодня мы рассмотрим некоторые моменты по обработке исключений в C#.
Рассмотрим канонический пример того, когда работа с программой приводит к генерации исключения — деление на ноль. Вот такой может быть наша программа:
Console.WriteLine("Введите любое целое число и нажмите Enter"); int i = int.Parse(Console.ReadLine()); double x = 5; double y = x / i; Console.WriteLine($"{x}/{i}={y}");
Теперь запустим программу и введем число 0
. В итоге, в Visual Studio мы увидим ошибку:
Мы получили исключение типа System.DivideByZeroException
(деление на ноль) и наше приложение аварийно завершило свою работу. Кроме этого, в таком простом, казалось бы, приложении имеется ещё одна уязвимость — пользователь может ввести совсем не то, что от него требуется и вместо числа введет, например, строку. В этом случае мы, опять же, получим в Visual Studio исключение:
Получили исключение типа System.FormatException
. Чтобы избежать подобного аварийного завершения программы, всё, что нам остается — это обработать исключения и выдавать пользователю не стандартное окошко с красным крестом, а сообщение, которое позволит скорректировать работу с программой и, например, повторить ввод.
Блок try…catch…finally
Для обработки исключений в C# используется специальная конструкция — блок try...catch...finally
. Перепишем наше приложение следующим образом:
Console.WriteLine("Введите любое целое число и нажмите Enter"); try { int i = int.Parse(Console.ReadLine()); int x = 5; double y = x / i; Console.WriteLine($"{x}/{i}={y}"); } catch { Console.WriteLine("Неправильный ввод значения"); } finally { Console.WriteLine("Выполнили блок finally"); } _ = Console.ReadLine();
Теперь запустим программу и снова введем значение 0
. В результате, программа не завершит работу аварийно, а выведет в консоль сообщение. Вот вывод консоли:
Введите любое целое число и нажмите Enter
0
Неправильный ввод значения
Выполнили блок finally
Приложение так же, как и в предыдущем примере, дошло до строки
double y = x / i;
однако, вместо аварийной остановки на строке с ошибкой, программа перешла в блок catch
и вывела сообщение «Неправильный ввод значения». После того, как выполнен блок catch
, программа переходит в блок finally
, выполняет все операции в нем и завершает работу.
В конструкции try...catch...finally
обязательным является блок try
. Блоки catch
или finally
могут отсутствовать, при этом следует отметить, что, если отсутствует блок catch
, то исключение будет возбуждено и программа аварийно завершит работу. Варианты использования конструкции try...finally...catch
могут быть такими:
//БЕЗ БЛОКА FINALLY. Программа не завершается аварийно try { int i = int.Parse(Console.ReadLine()); int x = 5; double y = x / i; Console.WriteLine($"{x}/{i}={y}"); } catch { Console.WriteLine("Неправильный ввод значения"); }
или
//БЕЗ БЛОКА CATCH. Программа аварийно завершит работу try { int i = int.Parse(Console.ReadLine()); int x = 5; double y = x / i; Console.WriteLine($"{x}/{i}={y}"); } finally { Console.WriteLine("Выполнили блок finally"); }
Блок finally
обычно используется для выполнения очистки ресурсов выделенных в блоке try
. Блок finally
не выполниться в том случае, если в блоке catch
также, как и в try
возникнет какое-либо исключение.
Перехват и обработка исключений в блоке catch
В примере с блоком catch
выше всё, что мы сделали — это вывели одно сообщение о том, что пользователь ввел неверное значение. При этом, при разработке реальных приложений часто необходимо не только сообщить пользователю об исключении, но и постараться направить его на «путь истинный». Например, в нашем тестовом приложении пользователь, как мы определили может:
- ввести 0 (исключение
System.DivideByZeroException
) - ввести вместо целого числа строку (исключение
System.FormatException
) - ввести вместо целого числа число с плавающей запятой (исключение
System.FormatException
) - ввести число, превышающее максимальное значение
int
(исключениеSystem.OverflowException
)
Во всех этих случаях мы должны каким-либо образом пояснить пользователю, что он сделал не так. Для этого, перепишем наш код с блокомcatch
следующим образом:
try { i = int.Parse(Console.ReadLine()); double y = x / i; Console.WriteLine($"{x}/{i}={y}"); } catch (System.DivideByZeroException e) { Console.WriteLine($"Деление на ноль! Исключение {e}"); } catch (System.FormatException e) { Console.WriteLine($"Введено не целое число! Исключение {e}"); } catch (System.OverflowException e) { Console.WriteLine($"Введите число в диапазоне от {int.MinValue} до {int.MaxValue}, исключая ноль. Исключение {e}"); }
здесь мы добавили сразу три блока catch
в каждом из которых происходит обработка исключений определенного типа. Для того, чтобы обработать исключение определенного типа мы использовали рядом с catch круглые скобки, в которых указали тип обрабатываемого исключения и соотнесли этот тип с именем исключения, которое в нашем случае было e
.
Следует также отметить, что далеко не всегда удается на этапе разработки предугадать абсолютна все типы исключений. Что, например, произойдет, если мы уберем из нашего кода блок, обрабатывающий System.OverflowException
? Правильно, мы снова нарвемся на аварийное завершение работы программы, так как компилятор пройдет по всем блокам catch
и не сможет соотнести тип исключение с именем. Чтобы такого не произошло, можно также предусмотреть при обработке исключений общий блок catch
в котором будет обрабатываться всё, что не попало в другие блоки. Например, мы можем сделать обработку двух типов исключений, а третий — обработаем в общем блоке:
catch (System.OverflowException e) { Console.WriteLine($"Введите число в диапазоне от {int.MinValue} до {int.MaxValue}, исключая ноль. Исключение {e}"); } catch (System.DivideByZeroException e) { Console.WriteLine($"Деление на ноль! Исключение {e}"); } //общий блок catch catch { Console.WriteLine("Неизвестная ошибка. Перезапустите программу"); }
Необходимо отметить, что важен не только факт наличия, но и порядок написания блоков catch
. Универсальный блок catch
должен находиться в самом низу кода. Об этом, кстати, Visual Studio сообщает. Если вы перенесете общий блок catch
и поставите его, например, над блоком, обрабатывающим исключение DivideByZeroException
, то Visual Studio выдаст ошибку:
Ошибка CS1017 Конструкции catch не могут использоваться после универсальной конструкции catch оператора try
Логические операции и обработка исключений в C#
Несмотря на то, что использование конструкции try..catch..finally
прекрасно позволяет перехватывать и обрабатывать различного типа исключения, её использование не всегда может быть оправдано, а некоторые исключения могут быть предвидены разработчиком и обработаны с использованием обычных логических операций. Например, в случае, если пользователь вводит не число, а непонятно что, можно было бы обойтись вот такой конструкцией:
if (int.TryParse(Console.ReadLine(), out i)) { y = x / i; Console.WriteLine($"{x}/{i}={y}"); } else { Console.WriteLine("Вы ввели не число!"); }
Здесь метод int.TryParse()
пробует преобразовать строку в целое число и, если преобразование прошло успешно, то возвращает true
. Таким образом, мы избежали использования конструкции try...catch
, которая, кстати, с точки зрения производительности более накладна, чем обычный условный оператор if
.
Итого
Сегодня мы познакомились с тем, как перехватывать и обрабатывать исключения в C#. Научились обрабатывать определенные типы исключений и в правильном порядке расставлять блоки catch в коде. Иногда мы можем повысить производительность нашего приложения, заменив, где это возможно и оправданно, конструкции try...catch
на обычные логические операции, например, используя условный оператор if
.
уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
How to simply and correctly check if user enters a number and not a char or string in C language? I’ve tried to write some loops containing:
if (scanf("%d",&number)=1)
but they never work or end. The loop should end when a number is entered.
BNL
7,0854 gold badges27 silver badges32 bronze badges
asked Nov 23, 2011 at 18:08
2
It should be
if (scanf("%d", &number) == 1) // Notice the two ='s, not just one
A single =
is the assignment operator, a double ==
is the equality test.
answered Nov 23, 2011 at 18:10
Seth CarnegieSeth Carnegie
73.6k22 gold badges181 silver badges249 bronze badges
3
I think you want this:
for (scanf(" %d", &number); (number < -100 || number > 100); scanf(" %d", &number)) {
printf("you didn't enter a valid number, try again >");
}
answered Nov 23, 2011 at 18:31
6
Your line should simply be:
if (scanf("%d",&number)){
If anything other than a number is entered, it will result in: if(0){
, instead of if(1){
answered Nov 24, 2011 at 15:31
JoelJoel
1971 silver badge10 bronze badges
Does this suit your context:
char ch;int g;
for(ch=getc(stdin);isalpha(ch);ch=getc(stdin))
{
printf("nenter numbers only");
while(isalpha(getc(stdin))){}
}
ungetc(ch,stdin);
scanf("%d",&g);
printf("number entered %d",g);
answered Nov 24, 2011 at 11:33
nikelnikel
3,31211 gold badges43 silver badges70 bronze badges