#c#
#c#
Вопрос:
Итак, это 2-й день моего самостоятельного обучения, я уверен, что это очень начинающий вопрос, но я ищу вещи, которые я нашел, используя typeof или tryparse, но, похоже, я не могу понять, как их использовать. Вероятно, мне не следует пробовать это на данном этапе обучения, но я решил, что все равно спрошу, потому что я действительно хочу знать, как это сделать. Я следую руководству, но оно не распространяется на то, является ли пользовательский ввод не числом. Это мой базовый калькулятор:
using System;
namespace Tutorials
{
class Program
{
static void Main(string[] args)
{
string opError = "Invalid Operator";
string numError = "Enter a valid number";
Console.Write("Enter a number: ");
double num1 = Convert.ToDouble(Console.ReadLine());
Console.Write("Enter Operator: ");
string op = Console.ReadLine();
Console.Write("Enter a number: ");
double num2 = Convert.ToDouble(Console.ReadLine());
if (op == " ")
{
Console.WriteLine(num1 num2);
}
else if (op == "-")
{
Console.WriteLine(num1 - num2);
}
else if (op == "/")
{
Console.WriteLine(num1 / num2);
}
else if (op == "*")
{
Console.WriteLine(num1 * num2);
}
else
{
Console.WriteLine(opError);
}
Console.ReadLine();
}
}
}
Я хочу иметь возможность проверить, является ли пользовательский ввод для num1 и num2 числом, и если это не так, я хочу, чтобы он отображал сообщение, которое я установил для NumError . Теперь операторы if и else имеют для меня смысл, потому что я знаю используемые операторы. Когда дело доходит до пользовательского ввода, это может быть что угодно. Вот где я запутался в том, как это сделать. Я читал о typeof и tryparse, но я не совсем понимаю, как использовать это в этом коде. Я попробовал это с помощью tryparse, но как только я ввожу число, оно ничего не делает, поэтому я предполагаю, что мне нужен оператор if в том, что я все еще слишком в начале, чтобы знать, как это сделать. Каков наилучший способ сделать это с моим кодом? Я вижу, что есть лучшие способы сделать этот калькулятор, я видел несколько примеров, но я пытаюсь понять это так, как у меня есть на данный момент.
Комментарии:
1. также убедитесь, что в вашем подразделении проверено значение 0 для num2 🙂
Ответ №1:
Одним из решений было бы использовать double.TryParse
, он возвращает, был ли ввод действительным числом и может использоваться внутри цикла do … while следующим образом:
double num1 = 0;
do {
Console.WriteLine("Enter a number:");
} while(!double.TryParse(Console.ReadLine(), out num1));
Который сообщает компьютеру продолжать запрашивать пользователя для ввода, пока синтаксический анализ не будет успешным, т. Е. Вы получили действительный номер.
Одна из проблем этого метода заключается в том, что он не сообщает пользователю, что пошло не так, только для продолжения ввода чисел. Но это относительно просто, и вы всегда получите число в конце.
Другим способом использования double.TryParse
и цикла было бы:
double num1 = 0;
while (true) {
Console.WriteLine("Enter a number:");
if (double.TryParse(Console.ReadLine(), out num1) {
// if the parse was successful, we can break out of the loop
break;
} else {
// if the parse was unsuccessful, display an error message and try again
Console.WriteLine("Invalid number. Try again.");
}
}
Эта версия более сложная, но она сообщает пользователю, что пошло не так, ИМО, она более удобочитаема, а также всегда будет получать число в конце.
Редактировать: добавлена вторая версия — спасибо @Tomek
Комментарии:
1. я знаю, что критерии цикла очень компактны, но вопрос в том, жертвуете ли вы удобочитаемостью и удобством обслуживания? Также кажется, что автор довольно новичок в materia, и я думаю, что автору было бы проще, если бы фокус был сосредоточен на более удобочитаемом коде, а не на его компактности. Может быть, вы можете добавить и другой вариант только для «новичков», как вы думаете?
2. @Tomek отличная идея! Я начну работать над этим прямо сейчас.
3. Спасибо, это сработало! Я попробовал второй метод, я обнаружил, что его легче понять. В первом я еще не знаю, что на самом деле делает «do». У меня есть несколько вопросов, поэтому я могу понять, что это сделало лучше. Я вроде понимаю TryParse, но тоже не совсем. Например, он преобразует строковую версию числа, и если он может ее преобразовать, он проходит, если не выходит из строя. Почему вы хотите преобразовать строку в число? Это что-то продвинутое, и мне просто пока не стоит об этом беспокоиться? Итак, в моем случае ввод, отличный от числа, приведет к сбою «преобразования», но разве это не цель TryParse?
4. Как будет выглядеть ситуация, если она успешно проанализирована? Также
double num1 = 0
почему num1 должно быть 0? Могло ли это быть любое число? Я просто предполагаю, это потому, что номер был присвоен num1, поэтому(double.TryParse(Console.ReadLine(), out num1))
он попытался проанализировать ввод в double, и если он прошел, то он прерывается, иначе он записывает сообщение об ошибке. Правильно ли это понимание? Извините, все еще пытаюсь запомнить и понять структуру синтаксиса.5. На «Как будет выглядеть ситуация, если она успешно проанализирована?» Я имею в виду, как при преобразовании строки в число. Или я просто неправильно понимаю TryParse здесь?
Ответ №2:
Не используйте Convert.ToDouble()
, который используется для преобразования между числовыми типами, а скорее вы должны использовать double.TryParse()
, который анализирует строку в число, например "1.234"
1.234
.
Смотрите пример ниже
class Program
{
static void Main(string[] args)
{
var input = Console.ReadLine();
if (double.TryParse(input, out double value))
{
// use 'value'
}
else
{
Console.WriteLine("Please enter a valid number.");
}
}
}
Ответ №3:
Просто используйте это вместо:
string c = Console.ReadLine();
int value;
if (int.TryParse(c, out value))
{ /* some code here */ }
Ответ №4:
Как вы уже выяснили, есть много способов решить эту проблему. Однако я бы не рекомендовал вам использовать такие методы, как TryParse(), если вы еще не чувствуете себя готовым к этому.
Поскольку вы сосредоточили свое внимание на операторе if-else, я подумал, что лучшим решением для вас может быть обработка ввода с помощью операторов try и catch, поскольку это очень похоже на оператор if-else .
Итак, вы, вероятно, знаете, что если вы попытаетесь преобразовать строку в числовой тип данных (например, int или double), вы получите сообщение об ошибке.
int number = Convert.ToInt32("some text"); //this will cause an error
Но на самом деле это идеальный способ узнать, является ли введенное значение числом или нет.
Теперь с помощью инструкции try-catch вы можете определить, вызовет ли инструкция ошибку без сбоя программы.
try
{
//some code
}
catch
{
//this code will be executed when the code above would result in an error
}
Возможно, вы видите некоторые сходства с if-else-statement .
Например, если код в блоке try вызывает ошибку, будет выполнен блок catch, иначе сам блок try.
Таким образом, вы могли бы попытаться преобразовать пользовательский ввод в число. Если ввод был строкой, вы можете вывести сообщение об ошибке с помощью catch-statement:
string input = Console.Readline();
double number = 0;
double defaultValue = 1;
try
{
number = Convert.ToDouble(input);
}
catch
{
Console.WriteLine(numError);
number = defaultValue;
}
Например, вместо использования значения по умолчанию вы также можете циклически вводить ввод, пока пользователь не введет действительное число или просто не завершит программу, но я думаю, что на данный момент этого достаточно =)
try и catch — очень полезные инструкции, вы все равно будете много работать с ними в будущем!
Комментарии:
1. Обычно считается плохой практикой использовать exceptions (
try { ... } catch { ... }
) в качестве потока управления2. Конечно, это не лучший метод. Я просто помню свою первую программу-калькулятор, которая выглядела так, и я бы не чувствовал себя хорошо, используя методы, которые я пока не понимаю.
3. Эквивалент
TryParse
— это очень простой API , на мой взгляд, не сложный или трудный для понимания. Смотрите Другие ответы для примера. Использование исключений в качестве потока управления в C #, как правило, является антишаблоном, которого вы хотите избежать.