0

I'm pretty new to C# and am wondering how I'd go about validating user input to meet the following requirements:

  • has to be a decimal type. if it isn't it should ask the user to enter a decimal value. (Which i believe i have covered in my code below)
  • also has to be within a specific range (1 - 1,000,000). If it isn't it should ask the user to enter a number within the correct range

What's the most efficient way of doing this considering i will have multiple user input to validate in the same sort of way.

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

EDITED BELOW

How about this?

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; line gave me an error so i left it out but the above seems to work?

7
  • Which technology are you using? WinForms? ASP.NET? ASP.NET MVC? You can try Data Annotations if possible. Commented Feb 20, 2015 at 12:09
  • Not sure what you mean by WinForms? ASP.NET? Commented Feb 20, 2015 at 12:11
  • I'm just accepting input from console. Commented Feb 20, 2015 at 12:12
  • You are creating an application. Codes do just provide logic to an application. What kind of application will use your code? OR if you are using Visual Studio, what is your Project Type? Commented Feb 20, 2015 at 12:12
  • What do you mean by efficient? You could modify your while to cover your range requirement: while (!decimal.TryParse(Console.ReadLine(), out balance) || balance < 1 || balance > 1000000) Commented Feb 20, 2015 at 12:24

2 Answers 2

1

I'd try something like:

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;
}

Then use it like:

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

If your min and max are fixed, then you could not pass them as arguments and use a fixed check. And you could also avoid having the query : $ passed in if needed, but I'll leave that to you

Update

The reason why the return val line was giving you an error was because you were inlining it (probably in a void returning function). What I was doing was making a function since you specified it needed to be reusable.

So in your program, you need to make a separate function... your program would look something like this:

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"));
    }
}

I've made a fiddle with the whole program so you can test online and make changes: https://dotnetfiddle.net/HiwwIP

Sign up to request clarification or add additional context in comments.

2 Comments

I made a function to allow reusage, but if you only need the inline code, then fine
@Bobby as a general rule in Stack Overflow, don't edit other's answers to add your own comments, just to fix mistakes or formatting, etc. I've updated my answer so you can see how my code was intended to be used and why the return statement was giving an error. I've added comments so you can see what happened and a fiddle for you to test
0

If I were you, I would do such:

        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();

Of course you can shortcut by eliminating bool definitions and directly calling functions instead; but I wrote in detail for clarity as you indicated that you are "pretty new".

3 Comments

Can the voter could at least elaborate for the reason of downvote so that I can fix it?
I downvoted for this: (balance <= 1 && balance > 1000000); which will obviously always be false. However you've edited it out now. But this still won't validate an input of 1 which I believe the OP wants. also has to be within a specific range (1 - 1,000,000)
Yeah I saw that as soon as I posted. Still thanks for pointing it out. I will correct <=1 issue asap.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.