如何在 C# 中将“0x310530”这样的字符串值转换为整数值?
我已经尝试过 int.TryParse (甚至 int.TryParse 与 System.Globalization.NumberStyles.Any),但它不起作用。
更新: 似乎 Convert.ToInt64 或 Convert.ToInt32 无需删除前导“0x”即可工作:
long hwnd = Convert.ToInt64("0x310530", 16);
Convert.ToInt64 Method (String, Int32)
的文档说:
“如果fromBase为16,则可以为该值指定的数字添加前缀 参数带有“0x”或“0X”。”
但是,我更喜欢像 TryParse 这样不会引发异常的方法。
int value = (int)new System.ComponentModel.Int32Converter().ConvertFromString("0x310530");
来自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
}
直接来自 SHanselman,正如 Cristi Diaconescu 所指出的,但我已经包含了主要源代码:
public static T GetTfromString<T>(string mystring)
{
var foo = TypeDescriptor.GetConverter(typeof(T));
return (T)(foo.ConvertFromInvariantString(mystring));
}
整篇文章值得仔细看!
如果删除前导 0x,则可以使用 int.Parse
int a = int.Parse("1310530", NumberStyles.AllowHexSpecifier);
在 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;
}
}
今天之前的所有答案都是对问题措辞的有效回答,但我怀疑他们可能错过了潜在的意图。如果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 中很容易获得)。