Reputation: 5811
How can I convert a string value like "0x310530" to an integer value in C#?
I've tried int.TryParse (and even int.TryParse with System.Globalization.NumberStyles.Any) but it does not work.
UPDATE: It seems that Convert.ToInt64 or Convert.ToInt32 work without having to remove the leading "0x":
long hwnd = Convert.ToInt64("0x310530", 16);
The documentation of Convert.ToInt64 Method (String, Int32)
says:
"If fromBase is 16, you can prefix the number specified by the value parameter with "0x" or "0X"."
However, I would prefer a method like TryParse that does not raise exceptions.
Upvotes: 32
Views: 53030
Reputation: 502
All the answers prior to today are valid responses to the wording of the question but I suspect that they might have missed the underlying intent. If the OP simply had one or more strings beginning "0x" then just skipping the first 2 characters would easily solve the problem with both int.Parse
and int.TryParse
(as already suggested by others). For mixed strings of hex digits where not all have an "0x" prefix, use of String.StartsWith(string)
could be used to identify those that need trimming. It would seem likely that most C# users would know about String.Substring(Int32)
as in the example by dtb. Using Convert.ToInt32(string? value, Int32 frombase)
does allow the "0x" to remain in place but only if frombase
is 16 meaning that, again, it is just skipping the "0x". I suspect that even if it was not the intent of the OP, most readers are here because (like me) they want to be able to automatically convert a string beginning "0x"/"0X" as hexadecimal but otherwise convert as decimal (as with strtol
from C and C++ or parseInt
from ECMAScript or, indeed, the C# language parser itself). Unfortunately, despite much searching, I think the simple answer is that you can't or, more precisely, there are no predefined classes that provide this functionality, you will have to do it yourself. Not that it is especially difficult...
// 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
Comments declaring me wrong and listing the class(es) which can do this (and which are readily available in older versions of .NET for those working on non-updatable systems) are very welcome.
Upvotes: 1
Reputation: 14508
Building further upon Caverna's answer I added a tryparse method so we can test if a conversion is valid to a certain type.
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;
}
}
Upvotes: 0
Reputation: 450
Direct from SHanselman, as pointed by Cristi Diaconescu, but I've included the main source code:
public static T GetTfromString<T>(string mystring)
{
var foo = TypeDescriptor.GetConverter(typeof(T));
return (T)(foo.ConvertFromInvariantString(mystring));
}
The whole article deserves a closer look!
Upvotes: 3
Reputation: 941327
int value = (int)new System.ComponentModel.Int32Converter().ConvertFromString("0x310530");
Upvotes: 31
Reputation: 217263
From MSDN:
NumberStyles.AllowHexSpecifier
Indicates that the numeric string represents a hexadecimal value. Valid hexadecimal values include the numeric digits 0-9 and the hexadecimal digits A-F and a-f. Strings that are parsed using this style cannot be prefixed with "0x" or "&h".
So you have to strip out the 0x
prefix first:
string s = "0x310530";
int result;
if (s != null && s.StartsWith("0x") && int.TryParse(s.Substring(2),
NumberStyles.AllowHexSpecifier,
null,
out result))
{
// result == 3212592
}
Upvotes: 18
Reputation: 10921
If you remove the leading 0x, you could use int.Parse
int a = int.Parse("1310530", NumberStyles.AllowHexSpecifier);
Upvotes: 1