Thread overview | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
July 17, 2007 read Hexadecimal value from string | ||||
---|---|---|---|---|
| ||||
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. |
July 17, 2007 Re: read Hexadecimal value from string | ||||
---|---|---|---|---|
| ||||
Posted in reply to Gilles G. | 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. Oddly, std.conv doesn't have a routine for it, as far as I am aware. Here's how I would do it. /* http://www.opensource.org/licenses/cpl1.0.php */ import std.string, std.stdio; import std.c.stdlib; long hexToLong(string s) { long v = strtoul(toStringz(s), null, 16); if (getErrno() == ERANGE) throw new Exception("Out of range"); return v; } void main() { writefln("%d",hexToLong("0xC")); } |
July 17, 2007 Re: read Hexadecimal value from string | ||||
---|---|---|---|---|
| ||||
Posted in reply to Gilles G. | 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 |
July 17, 2007 Re: read Hexadecimal value from string | ||||
---|---|---|---|---|
| ||||
Posted in reply to Gilles G. | When using Tango, this can be done like this: import tango.text.convert.Integer; int i = toInt( "12AB", 16 ); long l = toLong( "ffffFFFFAAAA", 16 ); see also: http://www.dsource.org/projects/tango/wiki/ChapterConversions and the source at http://www.dsource.org/projects/tango/browser/trunk/tango/text/convert/Integer.d Frank |
July 17, 2007 Re: read Hexadecimal value from string | ||||
---|---|---|---|---|
| ||||
Posted in reply to Frank Benoit | Frank Benoit Wrote: > When using Tango, this can be done like this: > > import tango.text.convert.Integer; > int i = toInt( "12AB", 16 ); > long l = toLong( "ffffFFFFAAAA", 16 ); > > see also: > http://www.dsource.org/projects/tango/wiki/ChapterConversions > and the source at > http://www.dsource.org/projects/tango/browser/trunk/tango/text/convert/Integer.d > > Frank Yep, Tango has some very kool functions. But I do want to point out that Phobos does have a radix parameter in the toString functions for converting a number to a string...sadly not the other way around. Here's an example: // Using Phobos you can convert a long or a ulong value, // using any base from 2 to 36 into a string private import ss = std.string; private import io = std.stdio; void main() { auto s = ss.toString(12uL, 16u); io.writefln("ss.toString(12uL, 16u)=\"%s\"", s); } /+ Output: C:\dmd>dmd strex1.d C:\dmd\bin\..\..\dm\bin\link.exe strex1,,,user32+kernel32/noi; C:\dmd>strex1 ss.toString(12uL, 16u)="C" C:\dmd> +/ David L. Davis |
July 17, 2007 Re: read Hexadecimal value from string | ||||
---|---|---|---|---|
| ||||
Posted in reply to David L. Davis | Reply to David,
> Yep, Tango has some very kool functions. But I do want to point out
> that Phobos does have a radix parameter in the toString functions for
> converting a number to a string...sadly not the other way around.
>
OK, brute force it is ;-b
|T fromString(T)(char[] str, uint r)
|{
| T v = T.min;
| goto start;
| do
| {
| v++;
| start:
| if(toString(v,r) == str) return v;
| }while(v != T.max);
|}
(bonus points if you can find more than three things to object to.)
|
July 17, 2007 Re: read Hexadecimal value from string | ||||
---|---|---|---|---|
| ||||
Posted in reply to BCS | BCS wrote: > Reply to David, > >> Yep, Tango has some very kool functions. But I do want to point out >> that Phobos does have a radix parameter in the toString functions for >> converting a number to a string...sadly not the other way around. >> > > OK, brute force it is ;-b > |T fromString(T)(char[] str, uint r) > |{ > | T v = T.min; > | goto start; > | do > | { > | v++; > | start: > | if(toString(v,r) == str) return v; > | }while(v != T.max); > |} :P > (bonus points if you can find more than three things to object to.) Without actually compiling that, I'll list some objections: 1) Let's get this one out of the way first: it's brute force. I mean, come on! 2) Since toString outputs uppercase characters (for digits > 9), this doesn't work for strings containing lowercase characters as digits. 3) It generates a lot of heap activity for anything that doesn't happen to be close to T.min (one string per iteration). Probably especially problematic for applications with small signed numbers or big numbers. This will probably mean lots of GC cycles. Arguably a symptom of (1). 4) It doesn't allow a redundant '+' at the start :P. 5) It appears from the Phobos source that toString(long value, uint radix) doesn't properly handle negative numbers when radix != 10. Though I guess that's a Phobos issue, not an issue in your code this cause the return value (if any[1]) answer given to be negative for T == long. After compiling (and verifying all above issues): 6) Doesn't compile for T other than long or ulong due to overload resolution issues (those are the only two types toString(T, uint radix) is defined for). 7) Very bad error checking. Out-of-range or plain invalid input (and input triggering (2), (4) and/or (5)) results in a failed assertion at the end of the function due to no return statement being executed. And if compiled in release mode it segfaults (executing a 'hlt' instruction put there by the implicit assert(0) at the end of the function). Did I miss anything? [1]: Due to some of the other issues, control may reach the end of the function without returning anything. |
July 17, 2007 Re: read Hexadecimal value from string | ||||
---|---|---|---|---|
| ||||
Posted in reply to Frits van Bommel | Reply to Frits, > BCS wrote: > >> Reply to David, >> >>> Yep, Tango has some very kool functions. But I do want to point out >>> that Phobos does have a radix parameter in the toString functions >>> for converting a number to a string...sadly not the other way >>> around. >>> >> OK, brute force it is ;-b >> |T fromString(T)(char[] str, uint r) >> |{ >> | T v = T.min; >> | goto start; >> | do >> | { >> | v++; >> | start: >> | if(toString(v,r) == str) return v; >> | }while(v != T.max); >> |} > :P > >> (bonus points if you can find more than three things to object to.) >> > Without actually compiling that, I'll list some objections: > 1) Let's get this one out of the way first: it's brute force. I mean, > come on! i++ > 2) Since toString outputs uppercase characters (for digits > 9), this > doesn't work for strings containing lowercase characters as digits. i++ > 3) It generates a lot of heap activity for anything that doesn't > happen > to be close to T.min (one string per iteration). Probably especially > problematic for applications with small signed numbers or big numbers. > This will probably mean lots of GC cycles. > Arguably a symptom of (1). i += 0 > 4) It doesn't allow a redundant '+' at the start :P. i++ > 5) It appears from the Phobos source that toString(long value, uint > radix) doesn't properly handle negative numbers when radix != 10. > Though > I guess that's a Phobos issue, not an issue in your code this cause > the return value (if any[1]) answer given to be negative for T == long. > After compiling (and verifying all above issues): i+=0 > 6) Doesn't compile for T other than long or ulong due to overload > resolution issues (those are the only two types toString(T, uint > radix) > is defined for). > 7) Very bad error checking. Out-of-range or plain invalid input (and > input triggering (2), (4) and/or (5)) results in a failed assertion at > the end of the function due to no return statement being executed. And > if compiled in release mode it segfaults (executing a 'hlt' > instruction > put there by the implicit assert(0) at the end of the function). i += ulong.max i>3 => bonus points <g> > Did I miss anything? > goto!!! > [1]: Due to some of the other issues, control may reach the end of the > function without returning anything. > |
July 18, 2007 Re: read Hexadecimal value from string | ||||
---|---|---|---|---|
| ||||
Posted in reply to BCS | BCS wrote:
> Reply to David,
>
>> Yep, Tango has some very kool functions. But I do want to point out
>> that Phobos does have a radix parameter in the toString functions for
>> converting a number to a string...sadly not the other way around.
>>
>
> OK, brute force it is ;-b
> |T fromString(T)(char[] str, uint r)
> |{
> | T v = T.min;
> | goto start;
> | do
> | {
> | v++;
> | start:
> | if(toString(v,r) == str) return v;
> | }while(v != T.max);
> |}
>
> (bonus points if you can find more than three things to object to.)
>
>
1. Using a for loop would be much clearer.
2. Using a goto is generally frowned upon; local gotos, though, especially in such simple cases, are usually readable. However, most programmers react viscerally to gotos. It is recommended that you avoid them unless you want your viscera removed.
3. In general, you shouldn't use != for loop boundaries unless *all* possible values other than that single value is still valid for the guts of the loop. If you were to refactor and make v into a real for all cases, for instance, you'd do a lot more work than necessary.
4. There is not guaranteed to be a toString(T, uint) method. T is not guaranteed to have increment and decrement overloads.
On the plus side, this executes in constant time and is a good example of code reuse.
For this, though, I think I'd use annealing. It's probably a bit faster, especially if I had several annealings executing in parallel.
|
July 18, 2007 Re: read Hexadecimal value from string | ||||
---|---|---|---|---|
| ||||
Posted in reply to Christopher Wright | Christopher Wright wrote: > BCS wrote: > >> Reply to David, >> >>> Yep, Tango has some very kool functions. But I do want to point out >>> that Phobos does have a radix parameter in the toString functions for >>> converting a number to a string...sadly not the other way around. >>> >> >> OK, brute force it is ;-b >> |T fromString(T)(char[] str, uint r) >> |{ >> | T v = T.min; >> | goto start; >> | do >> | { >> | v++; >> | start: >> | if(toString(v,r) == str) return v; >> | }while(v != T.max); >> |} >> >> (bonus points if you can find more than three things to object to.) >> >> > > 1. Using a for loop would be much clearer. i++ > 2. Using a goto is generally frowned upon; local gotos, though, especially in such simple cases, are usually readable. However, most programmers react viscerally to gotos. It is recommended that you avoid them unless you want your viscera removed. i++ //AAAaahh!!! ;) > 3. In general, you shouldn't use != for loop boundaries unless *all* possible values other than that single value is still valid for the guts of the loop. If you were to refactor and make v into a real for all cases, for instance, you'd do a lot more work than necessary. i++ > 4. There is not guaranteed to be a toString(T, uint) method. T is not guaranteed to have increment and decrement overloads. > i+=2 > On the plus side, this executes in constant time and is a good example of code reuse. > > For this, though, I think I'd use annealing. It's probably a bit faster, especially if I had several annealings executing in parallel. i-= large_number // that's even worse then mine!! //nice breakdown (bonus points to you) |
Copyright © 1999-2021 by the D Language Foundation