Проверка ввода нескольких пользователей в консольном приложении

Я новичок в С#, и мне интересно, как я могу проверить ввод пользователя, чтобы он соответствовал следующим требованиям:

  • должен быть десятичным типом. если это не так, он должен попросить пользователя ввести десятичное значение. (Что, я считаю, я рассмотрел в своем коде ниже)
  • также должно находиться в определенном диапазоне (1–1 000 000). Если это не так, он должен попросить пользователя ввести число в правильном диапазоне.

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

decimal balance;
Console.Write("Starting Balance: $");
while (!decimal.TryParse(Console.ReadLine(), out balance))
{
    Console.Write("Please enter a valid decimal value: $");
}

ОТРЕДАКТИРОВАНО НИЖЕ

Как насчет этого?

decimal balance;
Console.Write("Starting Balance: $");
while(true)
{
    if (!decimal.TryParse(Console.ReadLine(), out balance))                
        Console.Write("Please enter a valid decimal value: $");
    else if (balance < 1 || balance > 100)
        Console.Write("Please enter an amount between 1 and 100: ");
    else
        break;                
}
Console.WriteLine("Balance entered is: " + balance.ToString("n"));

Строка return val; выдала мне ошибку, поэтому я ее пропустил, но, похоже, вышеприведенное работает?


person Boo    schedule 20.02.2015    source источник
comment
Какую технологию вы используете? WinForms? АСП.НЕТ? ASP.NET MVC? Вы можете попробовать аннотации данных, если это возможно.   -  person user3021830    schedule 20.02.2015
comment
Не знаете, что вы подразумеваете под WinForms? АСП.НЕТ?   -  person Boo    schedule 20.02.2015
comment
Я просто принимаю ввод с консоли.   -  person Boo    schedule 20.02.2015
comment
Вы создаете приложение. Коды просто обеспечивают логику для приложения. Какое приложение будет использовать ваш код? ИЛИ, если вы используете Visual Studio, какой у вас тип проекта?   -  person user3021830    schedule 20.02.2015
comment
Что вы подразумеваете под эффективным? Вы можете изменить время, чтобы удовлетворить требования диапазона: while (!decimal.TryParse(Console.ReadLine(), out balance) || balance < 1 || balance > 1000000)   -  person DGibbs    schedule 20.02.2015
comment
Как я могу сделать это, отправив 2 отдельных сообщения. 1 сообщение, если оно не входит в диапазон, и другое, если оно не является допустимым десятичным числом?   -  person Boo    schedule 20.02.2015
comment
вы можете использовать вложенные операторы if, то есть if внутри другого.   -  person mcy    schedule 20.02.2015


Ответы (2)


Я бы попробовал что-то вроде:

decimal GetUserInput(string inputQuery, decimal min, decimal max)
{
  Console.Write(inputQuery);
  decimal val;
  while(true)
  {
    if(!decimal.TryParse(Console.ReadLine(), out val))
      Console.Write("Please enter a valid decimal value: $");
    else if(val < min || val > max)
      Console.Write("Please enter an amount between " + min + " and " + max + ": $");
    else // the value is a decimal AND it's correct
      break;
  } 
  return val;
}

Затем используйте его как:

var startingBalance = GetUserInput("Starting Balance: $", 1, 100000);
var endingBalance = GetUserInput("Ending Balance: $", 1, 100000);
//...

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

Обновлять

Причина, по которой строка return val выдавала вам ошибку, заключалась в том, что вы ее встраивали (вероятно, в функции, возвращающей void). Что я делал, так это создавал функцию, поскольку вы указали, что ее нужно использовать повторно.

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

class Program
{
    // We're declaring this function static so you can use it without an instance of the class
    // This is a function, so it can be called multiple times, with different arguments
    static decimal GetUserInput(string inputQuery, decimal min, decimal max)
    {
      // Write the argument "inputQuery" to console
      Console.Write(inputQuery);
      decimal val;

      // Loop indefinitely
      while(true)
      {
        // Read from console into a decimal "val"
        if(!decimal.TryParse(Console.ReadLine(), out val))
          // It was not a correct decimal, so write the prompt
          Console.Write("Please enter a valid decimal value: $");
        // It was a correct decimal
        else if(val < min || val > max)
          // But not in range, so write a different prompt
          Console.Write("Please enter an amount between " + min + " and " + max + ": $");
        // It was a decimal and within range
        else
          // so we break the infinite loop and exit after the "}"
          break;

        // If we have got to this point (we didn't hit the "break"),
        // it was either not a decimal or it wasn't within range, 
        // so it'll loop again and ask for a value from console again.
        // The prompt was already written above (in the "ifs")

      } 
      // We got out of the while(true){} loop, so it means we hit "break"
      // above, and that means "val" contains a correct value (decimal and
      // within range), so we return it to the caller
      return val;
    }

    static void Main()
    {
      // Your original code went here, but see how my function is *outside* function Main()

      // You use my function (GetUserInput) here:
      var startingBalance = GetUserInput("Starting Balance: $", 1, 100000);
      var endingBalance = GetUserInput("Ending Balance: $", 1, 100000);

      // Then with the returned values (stored in "startingBalance"
      // and "endBalance"), you can do what you want:
      Console.WriteLine("Starting balance was: " + startingBalance.ToString("n"));
    }
}

Я переделал всю программу, чтобы вы могли тестировать ее онлайн и вносить изменения: https://dotnetfiddle.net/HiwwIP< /а>

person Jcl    schedule 20.02.2015
comment
Я сделал функцию, позволяющую повторное использование, но если вам нужен только встроенный код, то ладно - person Jcl; 20.02.2015
comment
@Bobby, как общее правило в Stack Overflow, не редактируйте чужие ответы, чтобы добавить свои собственные комментарии, просто для исправления ошибок или форматирования и т. д. Я обновил свой ответ, чтобы вы могли видеть, как мой код предназначен для использования и почему оператор return выдавал ошибку. Я добавил комментарии, чтобы вы могли увидеть, что произошло, и скрипку для тестирования. - person Jcl; 20.02.2015

Если бы я был вами, я бы сделал так:

        bool isInvalid, isOutOfRange;
        decimal balance = 0;
        isOutOfRange = true;
        do
        {
            string input = Console.ReadLine();
            isInvalid = !Decimal.TryParse(input, out balance);
            if (!isInvalid)
            {
                // use balance<=1 if 1 should not be included
                // use balance>=1000000 if 1000000 should not be included
                isOutOfRange = (balance < 1 || balance > 1000000);
            }
            if (isInvalid)
            {
                Console.WriteLine("Please enter a valid decimal value: $");
            }
            else if (isOutOfRange)
            {
                Console.WriteLine("Please enter value between 1 and 1000000: $");
            }

        } while (isInvalid || isOutOfRange);
        Console.WriteLine("{0}, That is a valid value!", balance.ToString());
        Console.ReadKey();

Конечно, вы можете сократить путь, исключив bool определения и вместо этого напрямую вызывая функции; но я подробно написал для ясности как вы указали что вы "новенький".

person mcy    schedule 20.02.2015
comment
Может ли голосующий хотя бы уточнить причину понижения голоса, чтобы я мог это исправить? - person mcy; 20.02.2015
comment
Я проголосовал за это: (balance <= 1 && balance > 1000000);, что, очевидно, всегда будет ложным. Однако вы отредактировали его сейчас. Но это все равно не подтвердит ввод 1, который, как я полагаю, хочет ОП. also has to be within a specific range (1 - 1,000,000) - person DGibbs; 20.02.2015
comment
Да, я увидел это, как только написал. Все равно спасибо, что указали. Я исправлю ‹=1 проблему как можно скорее. - person mcy; 20.02.2015