二进制字符串转整数

49
我有一个二进制字符串,由用户输入,我需要将其转换为整数。
起初,我天真地使用了这个简单的语句:
Convert.ToInt32("11011",2);

不幸的是,如果用户直接输入整数,这将抛出异常。

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

如何确保用户输入的字符串是二进制字符串?

  • try..catch
  • Int32.TryParse

谢谢!


1
用户如何输入字符串?如果是表单,你不能限制它只接受 '0' 和 '1' 吗? - outis
3
try - catch 为什么被认为“丑陋”? - RaYell
你可能是对的,这并不那么难看。我现在实际上选择了它,因为十六进制值也突然变得可行了。因此,一些简单的尝试-catch语句只是最简单和最容易的解决方案。谢谢大家。 - eric
2个回答

35

你可以使用正则表达式来检查它是否为 "^[01]+$"(或更好的是 "^[01]{1,32}$"),然后再使用 Convert?

当然,异常情况可能不会是一个巨大的问题!不够优雅?也许。但它们能用。

例如(以垂直空间格式化):

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

1
这段代码无法正确处理 Convert.ToString((long)Int32.MaxValue + 1, 2) 的转换。本应该被拒绝,但错误地转换成了 Int32.MinValue。 - Ben Lings
2
为什么会被拒绝呢?这是一个合法的32位二进制值。如果你选择将其解释为int32,那当然了:任何带有msb设置的值都将是负数...那又怎样呢? - Marc Gravell
谢谢你提供的好方法。我最终决定采用它。但是需求稍有变化,所以我认为使用 try-catch 是最简单和最清晰的解决方案。 - eric
我没有太多的正则表达式经验,这个检查是确认有1-32个字符,且这些字符必须是0或1吗?如何最好地检查有效的八进制字符串?我希望.NET有一个int.TryParse,可以检查二进制和八进制,而不仅仅是十进制和十六进制。 - R1PFake
@R1PFake 是的,^...$ 测试字符串的开头/结尾(即:没有其他内容);[01] 表示“0或1”,{1,32} 表示“1到32次,包括1和32”。 - Marc Gravell

4

感谢您的迅速回复!

不幸的是,我的要求已经改变。现在用户可以输入任何格式:二进制、十进制、十六进制。因此,我决定使用 try-catch 提供最简单和最清晰的解决方案。

为了保险起见,我现在发布我正在使用的代码。我认为它非常清晰,甚至有些优雅,至少我是这么认为的^^。

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

感谢您鼓励我使用try-catch,我认为这真正提高了我的代码的可读性。
谢谢。

1
你不喜欢八进制吗?但是说真的,如果有人输入“11”并且是以十进制为基础呢?标准解决方案是使用前缀('0b','','0x'),但这可能不符合您的要求。 - outis
1
是的,不使用八进制^^。用户实际上必须在组合框中选择要使用的格式。我也考虑过你的解决方案,但使用组合框似乎更容易。非常感谢你的建议。 - eric

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接