将包含以“0x”开头的十六进制值的字符串转换为整数或长整型

问题描述 投票:0回答:6

如何在 C# 中将“0x310530”这样的字符串值转换为整数值?

我已经尝试过 int.TryParse (甚至 int.TryParseSystem.Globalization.NumberStyles.Any),但它不起作用。

更新: 似乎 Convert.ToInt64 或 Convert.ToInt32 无需删除前导“0x”即可工作:

long hwnd = Convert.ToInt64("0x310530", 16);

Convert.ToInt64 Method (String, Int32)
的文档说:

“如果fromBase为16,则可以为该值指定的数字添加前缀 参数带有“0x”或“0X”。”

但是,我更喜欢像 TryParse 这样不会引发异常的方法。

c# integer hex
6个回答
32
投票
int value = (int)new System.ComponentModel.Int32Converter().ConvertFromString("0x310530");

18
投票

来自MSDN

NumberStyles.AllowHexSpecifier

表示数字字符串代表十六进制值。有效的十六进制值包括数字 0-9 以及十六进制数字 A-F 和 a-f。使用此样式解析的字符串不能以“0x”或“&h”为前缀

所以你必须先去掉

0x
前缀:

string s = "0x310530";
int result;

if (s != null && s.StartsWith("0x") && int.TryParse(s.Substring(2),
                                                    NumberStyles.AllowHexSpecifier,
                                                    null,
                                                    out result))
{
    // result == 3212592
}

3
投票

直接来自 SHanselman,正如 Cristi Diaconescu 所指出的,但我已经包含了主要源代码:

public static T GetTfromString<T>(string mystring)
{
   var foo = TypeDescriptor.GetConverter(typeof(T));
   return (T)(foo.ConvertFromInvariantString(mystring));
}

整篇文章值得仔细看!


1
投票

如果删除前导 0x,则可以使用 int.Parse

int a = int.Parse("1310530", NumberStyles.AllowHexSpecifier);

0
投票

在 Caverna 的答案的基础上,我添加了一个 tryparse 方法,以便我们可以测试转换对于某种类型是否有效。

public static T GetTfromString<T>(string mystring)
{
    var foo = TypeDescriptor.GetConverter(typeof(T));
    return (T)(foo.ConvertFromInvariantString(mystring));
}

public static bool TryGetTFromString<T>(string mystring, out T value)
{
    try
    {
        value = GetTfromString<T>(mystring);
        return true;
    }
    catch (FormatException)
    {
        value = default(T);
        return false;
    }
}

0
投票

今天之前的所有答案都是对问题措辞的有效回答,但我怀疑他们可能错过了潜在的意图。如果OP只是有一个或多个以“0x”开头的字符串,那么只需跳过前2个字符就可以轻松解决

int.Parse
int.TryParse
的问题(正如其他人已经建议的那样)。对于并非全部都有“0x”前缀的混合十六进制数字字符串,可以使用
String.StartsWith(string)
来识别需要修剪的字符串。大多数 C# 用户似乎都知道
String.Substring(Int32)
,如 dtb 的示例所示。使用
Convert.ToInt32(string? value, Int32 frombase)
确实允许“0x”保留在原位,但前提是
frombase
为 16,这意味着它只是跳过“0x”。我怀疑即使这不是OP的意图,大多数读者都在这里,因为(像我一样)他们希望能够自动将以“0x”/“0X”开头的字符串转换为十六进制,否则转换为十进制(就像 C 和 C++ 中的
strtol
或 ECMAScript 中的
parseInt
或 C# 语言解析器本身一样)。不幸的是,尽管进行了大量搜索,我认为简单的答案是您不能,或者更准确地说,没有提供此功能的预定义类,您必须自己完成。并不是说特别困难...

// Ignoring checks that s is not null but if this were a member function
// of a class in a library then all relevant checks should be included.

string  s = "0x1310530";
int     value;

// using Parse needs exception handling

if (s.Length > 1 && s.Substring(0, 2).ToLowerInvariant() == "0x")
    value = int.Parse(s.Substring(2), NumberStyles.AllowHexSpecifier);
else
    value = int.Parse(s);

// using TryParse avoids exceptions (unless the NumberStyles argument is invalid)

bool    parseok;

if (s.Length > 1 && s.Substring(0, 2).ToLowerInvariant() == "0x")
    parseok = int.TryParse(s.Substring(2), NumberStyles.AllowHexSpecifier, null, out value);
else
    parseok = int.TryParse(s, out value);

// using Convert.ToInt32 for just hex or decimal (note: exceptions)

int     frombase = 10;

if (s.Length > 1 && s.Substring(0, 2).ToLowerInvariant() == "0x")
    frombase = 16;
value = Convert.ToInt32(s, frombase); // don't need to remove the 0x

// using Convert.ToInt32 allows the possibility of octal and binary as well

bool     skipprefix = false;

if (s.Length > 1 && s[0] == '0')
// single digits or no leading 0 means convert as decimal string
// "" will generate ArgumentOutOfRangeException as expected
        switch(s[1]) // can't be just "0", already checked that
        {
        case 'x':
        case 'X':
                frombase = 16;
                break;

        case 'b':
        case 'B':
                frombase = 2;
                skipprefix = true;
                break;

        default:
                frombase = 8;
                break;
        }
value = Convert.ToInt32(skipprefix ? s.Substring(2) : s, frombase);
// still don't need to remove leading "0x" or "0" but "0b" must go

非常欢迎声明我错误的评论并列出可以执行此操作的类(对于那些在不可更新系统上工作的人来说,这些类在旧版本的 .NET 中很容易获得)。

© www.soinside.com 2019 - 2024. All rights reserved.