Как проверить, не является ли пользовательский ввод числом, а затем отобразить сообщение на C #?

#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 #, как правило, является антишаблоном, которого вы хотите избежать.