read Hexadecimal value from string
David L. Davis
SpottedTiger at yahoo.com
Tue Jul 17 13:25:49 PDT 2007
Gilles G. Wrote:
> Hello,
> I try to read hexadecimal values from a file.
> I tryed to use toInt, for example:
> auto i = toInt("C");
> but this doesn't work.
> What is the method to read hexadecimal value?
>
> Thanks.
Hi Gilles,
You're welcome to used some D code I wrote that's Public Domain listed below:
/+
' Module : hexconv.d
' Author : David L. 'SpottedTiger' Davis
' Tested : dmd v2.002 (WinXP OS/ Intel CPU)
' Licence : Public Domain / Contributed to Digital Mars
' =====================================================
' To complie for a unittest:
' dmd hexconv.d -debug=hexconv -unittest
'
' To compile a D program that uses hexconv.d:
' dmd MySource.d hexconv.d
+/
module hexconv;
debug( hexconv ) private import std.stdio;
// Function : xtoul() - Hex string to an unsigned decimal whole number
// Author : David 'SpottedTiger' L. Davis
// Created : 03.May.05
// CPU : Intel x86 (Numercials stored as "Low byte to High byte")
// Last Test: dmd v2.002
// ----------------------------------------
// Converts a Hex string from 0x0 to 0xFFFFFFFFFFFFFF
// into a ulong value 0 to 18,446,744,073,709,551,615
// also it handles the lowercase 'a' thru 'f'.
ulong xtoul(string sx)
{
ulong ul = 0L;
int j = 7;
char c, c1, c2;
char[] st = cast(char[])sx;
int len = st.length;
const char[] zeros = "0000000000000000"c;
union u { ulong ul; char[8] c; }
u U;
if (len == 0 || len > 16)
throw new Exception( "xtoul() the string parameter is either an empty string,"c ~
" or its length is greater than 16 characters."c );
// isHex()
for (int i = 0; i < st.length; i++)
{
//c = ( sx[i] > 'F' ? sx[i] - 32 : sx[i] );
c = st[i];
if ((c >= '0' && c <= '9') ||
(c >= 'A' && c <= 'F') ||
(c >= 'a' && c <= 'f'))
continue;
else
throw new Exception("xtoul() invalid hex character used."c);
}
if (len < 16)
st = zeros[0..16 - len] ~ st;
j = 7;
for (int i = 0; i < 16; i += 2)
{
c1 = (st[i] > 'F' ? st[i] - 32 : st[i]);
c2 = (st[i + 1] > 'F' ? st[i + 1] - 32 : st[i + 1]);
c1 = cast(int)(c1 > 52 ? c1 - 55 : c1 - 48) << 4;
U.c[j--] = c1 + cast(int)(c2 > 52 ? c2 - 55 : c2 - 48);
}
return U.ul;
}
unittest
{
debug( hexconv ) writefln( "hexconv.xtoul( string ).unittest"c );
ulong ul;
ul = xtoul("0"c);
assert( ul == 0x0 );
ul = xtoul("FF"c);
assert( ul == 0xFF );
ul = xtoul("eea"c);
assert( ul == 0xEEA );
ul = xtoul("AB"c);
assert( ul == 0xAB );
ul = xtoul("ABCD"c);
assert( ul == 0xABCD );
ul = xtoul("A12CD00"c);
assert( ul == 0xA12CD00 );
ul = xtoul("FFFFFFFFFFFFFFFF"c);
assert( ul == 0xFFFFFFFFFFFFFFFF );
}
// Function : ultox() - Decimal unsigned whole number to Hex string
// Author : David 'SpottedTiger' L. Davis
// Created : 04.May.05
// CPU : Intel x86 (Numercials stored as "Low byte to High byte")
// Last Test: dmd v2.002
// -----------------------------------------
// Accepts any positive number from 0 to 18,446,744,073,709,551,615
// and the returns an even number of hex strings up to 16 characters
// (from 0x0 to 0xFFFFFFFFFFFFFF).
string ultox(in ulong ul)
{
char[16] sx;
char c1, c2;
union u { ulong ul; char[8] c; }
int i = 0, j = 0, k = 0;
bit z = true;
u U;
U.ul = ul;
for (i = 7; i >= 0; i--)
{
c1 = U.c[i] >> 4;
c1 = cast(char)(c1 > 9 ? c1 + 55 : c1 + 48);
c2 = U.c[i] & 0x0F;
c2 = cast(char)(c2 > 9 ? c2 + 55 : c2 + 48);
if (z && c1 == '0' && c2 == '0')
continue;
z = false;
sx[j++] = c1;
sx[j++] = c2;
}
if (j > 0)
//Copying a fixed array into a dynamic array, must COW.
return sx[0..j].dup;
else
return "00"c;
}
unittest
{
debug( hexconv ) writefln( "hexconv.ultox( in ulong ).unittest"c );
string sx;
sx = ultox(0); //0x0
assert( sx == "00"c );
sx = ultox(255); //0xFF
assert( sx == "FF"c );
sx = ultox(171); //0xAB
assert( sx == "AB"c );
sx = ultox(43981); //0xABCD
assert( sx == "ABCD"c );
sx = ultox(169004288); //0xA12CD00
assert( sx == "0A12CD00"c );
sx = ultox(0xA12CD00); //169004288
assert( sx == "0A12CD00"c );
sx = ultox(ulong.max); //0xFFFFFFFFFFFFFFFF
assert( sx == "FFFFFFFFFFFFFFFF"c );
}
bool isHex(string sx)
{
char c;
for (int i = 0; i < sx.length; i++)
{
c = sx[i];
if ((c >= '0' && c <= '9') ||
(c >= 'A' && c <= 'F') ||
(c >= 'a' && c <= 'f'))
continue;
else
return false;
}
return true;
}
unittest
{
debug( hexconv ) writefln( "hexconv.isHex( string ).unittest"c );
assert( isHex("00"c) );
assert( isHex("FF"c) );
assert( isHex("Ffae0"c) );
assert( isHex("AB"c) );
assert( isHex("abdef"c) );
assert( isHex("ABCD"c) );
assert( isHex("0A12CD00"c) );
assert( isHex("FFFFFFFFFFFFFFFF"c) );
assert( isHex("00ER"c) == false );
assert( !isHex("0xW"c) );
}
debug( hexconv )
{
int main()
{
auto i = xtoul("C");
writefln("i=%d, xtoul(\"C\")=%d, ultox(i)=\"%s\"", i, xtoul("C"), ultox(i));
writefln( "unittest done"c );
return 0;
}
}
Best Regards,
David L. Davis
More information about the Digitalmars-d-learn
mailing list