views:

421

answers:

2

Hello,

I have a binary string, entered by the user, which I need to convert to an integer.

At first I naivly used this simple line:

Convert.ToInt32("11011",2);

Unfortunately this throws an exception if the user enters the integer directly.

Convert.ToInt32("123",2); // throws Exception

How can I make sure that the string entered by the user actually is a binary string?

  • try..catch....but that's just too ugly.
  • something like 'Int32.TryParse' maybe.

Thanks

+5  A: 

You could use a Regex to check that it is "^[01]+$" (or better, "^[01]{1,32}$"), and then use Convert?

of course, exceptions are unlikely to be a huge problem anyway! Inelegant? maybe. But they work.

Example (formatted for vertical space):

static readonly Regex binary = new Regex("^[01]{1,32}$", RegexOptions.Compiled);
static void Main() {
    Test("");
    Test("01101");
    Test("123");
    Test("0110101101010110101010101010001010100011010100101010");
}
static void Test(string s) {
    if (binary.IsMatch(s)) {
        Console.WriteLine(Convert.ToInt32(s, 2));
    } else {
        Console.WriteLine("invalid: " + s);
    }
}
Marc Gravell
+1 That is what I was thinking as well.
Andrew Hare
This doesn't correctly handle conversion of Convert.ToString((long)Int32.MaxValue + 1, 2). This should be rejected but is incorrectly converted to Int32.MinValue.
Ben Lings
Why should that be rejected? It is a valid 32-bit binary value. If you choose to interpret it as int32 then sure: anything with the msb set is going to be negative... and?
Marc Gravell
Thanks great solution. I actually went with it. But the requirements changed some what so I decided try - catch is the simplest and cleanest solution
oreon
A: 

Thanks for the great and incredibly fast answer!

Unfortunaetly my requirements changed. Now the user can pretty much enter any format. Binary, Decimal, Hex. So I decided try - catch just provides the simplest and cleanest solution.

So just for good measure I am posting the code I am using now. I think it is pretty clear and even somewhat elegant, or so I think^^.

switch (format)
{
    case VariableFormat.Binary:
        try
        {
            result = Convert.ToInt64(value, 2)
        }
        catch
        {
            // error handling
        }
        break;
    case VariableFormat.Decimal:
        try
        {
            result = Convert.ToInt64(value, 10)
        }
        catch
        {
            // error handling
        }
        break;
    case VariableFormat.Hexadecimal:
        try
        {
            result = Convert.ToInt64(value, 16)
        }
        catch
        {
            // error handling
        }
        break;
}

So thanks for encouraging me to use try - catch, I think it really improved the readibility of my code.

Thanks

oreon
What, you don't like octal? Seriously though, what if someone enters '11' and meant it in base 10? Standard solution would be to use a prefix ('0b', '', '0x'), but that may not fit your requirements.
outis
Yeah no octal^^. The user actually has to choose in combobox which format she wants to use. I thought about your solution too, but it seemed easier with a combobox. Thanks so great input.
oreon