Валидиране на въведените от множество потребители в конзолното приложение

Аз съм доста нов в C# и се чудя как да потвърдя въведеното от потребителя, за да отговаря на следните изисквания:

  • трябва да е десетичен тип. ако не е, трябва да поиска от потребителя да въведе десетична стойност. (Което смятам, че съм покрил в моя код по-долу)
  • също трябва да бъде в определен диапазон (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? ASP.NET MVC? Можете да опитате анотации към данни, ако е възможно.   -  person user3021830    schedule 20.02.2015
comment
Не сте сигурни какво имате предвид под WinForms? ASP.NET?   -  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);
//...

Ако вашите min и max са фиксирани, тогава не можете да ги предадете като аргументи и да използвате фиксирана проверка. Можете също така да избегнете предаването на заявката : $, ако е необходимо, но ще оставя това на вас

Актуализация

Причината, поради която редът 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, което според мен OP иска. also has to be within a specific range (1 - 1,000,000) - person DGibbs; 20.02.2015
comment
Да, видях това веднага щом публикувах. Все пак благодаря, че го посочи. Ще коригирам ‹=1 проблем възможно най-скоро. - person mcy; 20.02.2015