views:

106

answers:

3

Hi, I am new to c#, and I can't figure out why I keep getting a 'FormatException was unhandled' error when I run this method:

public void bet()
{
    int betAmount;

    Console.WriteLine("How much would you like to bet?");
    betAmount = int.Parse(Console.ReadLine());
    Console.WriteLine(_chips - betAmount);
} 

The program does not stop to wait for user input, and I don't know why this is?

What can I do to get the program to wait for the user's input in this method?

**I was running the program on Microsoft Visual C# 2010 Express as a console application.

+7  A: 

You need to handle the case where Console.ReadLine() returns something that is not an integer value. In your case, you're probably getting that error because something is typed incorrectly.

You can solve this by switching to TryParse:

public void bet()
{
    int betAmount;

    Console.WriteLine("How much would you like to bet?");
    while(!int.TryParse(Console.ReadLine(), out betAmount))
    {
        Console.WriteLine("Please enter a valid number.");
        Console.WriteLine();
        Console.WriteLine("How much would you like to bet?");
    }

    Console.WriteLine(_chips - betAmount);
} 

int.TryParse will return false if the user types something other than an integer. The above code will cause the program to continually re-prompt the user until they enter a valid number instead of raising the FormatException.

This is a common problem - any time you are parsing user generated input, you need to make sure the input was entered in a proper format. This can be done via exception handling, or via custom logic (as above) to handle improper input. Never trust a user to enter values correctly.

Reed Copsey
I think TryParse is a weakness in this as you say - "Never trust a user to enter values correctly", that is where the weakness point is, that explains my point about the regex which is bullet-proof " any time you are parsing user generated input, you need to make sure the input was entered in a proper format" - it traps out bad input..
tommieb75
@tommieb75: That's exactly what TryParse does for you - it handles this without exceptions, and without forcing the regular expression, plus it handles it with localization, etc.
Reed Copsey
@Reed: ok - that's fine and dandy so! +1 from me... didn't think of the localization there... meh!
tommieb75
A: 

Might be better and more bulletproof to do a regex against the input for digits such as for example:

public static Regex NumInpRegex = new Regex(
      "^(?<inp_num>\\d+)$",
    RegexOptions.IgnoreCase
    | RegexOptions.Singleline
    | RegexOptions.ExplicitCapture
    | RegexOptions.CultureInvariant
    | RegexOptions.IgnorePatternWhitespace
    | RegexOptions.Compiled
    );
string InputText = Console.ReadLine();
Match m = NumInpRegex.Match(InputText);
if (m.Success && InputText.Length > 0){
    betAmount = int.Parse(m.Groups["inp_num"].Value);
    Console.WriteLine(_chips - betAmount);
}
tommieb75
Wow - that really seems like overkill when a simple TryParse would tell you the same thing.
Reed Copsey
@Reed: Maybe... but its foolproof, does not raise a FormatException..
tommieb75
@tommieb75: Neither does `int.TryParse`.
Dan Tao
Well thanks to whoever down-voted - at least it's backward compatible across different .NET versions....also, you can be assured that user input in this is trusted as the regex traps that out...
tommieb75
Not foolproof, this regex matches input such as "999999999999999999999999", which will throw an exception in the Parse method.
Juliet
@Juliet: due to "telepathic communication", you warned me of that, let's just say I experienced a regexp overload this afternoon .... meh! :P
tommieb75
A: 

Are you using Visual Studio? Some other IDEs may by default run console apps in a non-interactive mode. For example I know that in MonoDevelop you have to specifically change the project properties so that the program runs in an external console if you want to do that.

Dan Tao