[C++] convert hexadecimal string into decimal integer (updated)
2012/04/07 1件のコメント
一年ほど前に、16 進数の文字列を 10 進数に変換するコードを紹介しました。
[Win32] [C++] convert hexadecimal string into decimal integer
https://msmania.wordpress.com/2011/02/15/win32-c-convert-hexadecimal-string-into-decimal-integer/
このときのコードは wstringstream を使ういい加減な処理で応用範囲が狭いため、もっと汎用的なコードを書いてみました。数ヶ月前から使っていて実用にも耐えているので、前回より遥かにマシです。
メインの関数は wtoi64 で、文字列を 64bit 整数に変換します。デバッガーと併用することが多いので、以下のフォーマットに対応しています。
[16 進表記]
0xFFFFFFFF`FFFFFFFF
0xFFFFFFFF
FFFFFFFF
FFFFFFFF`FFFFFFFF
FFFFFFFFFFFFFFFF
[10 進表記]
0n12345678901234
12345678901234
デバッガーと異なって、0x や 0n の接頭辞を付けない場合の既定は 10 進数にしています。16 進を既定にするには、Category==cUnknown の場合の Category を cDec ではなく cHex に変更して下さい。(青字部分)
ソースはこれです。
//
// convert.cpp
//#include <ctype.h>
#include <stdlib.h>#define GET_HIDWORD(ll) (*(((int*)(&ll))+1))
#define GET_LODWORD(ll) (*((int*)(&ll)))bool wtoi64(wchar_t *String, unsigned long long *ll);
int htoi(wchar_t c) {
if ( iswdigit(c) ) return c-L’0′;
if ( c>=L’a’ && c<=L’f’ ) return c-L’a’+10;
if ( c>=L’A’ && c<=L’F’ ) return c-L’A’+10;
return 0;
}int htoi(const wchar_t *s) {
int Ret= 0;
const wchar_t *p= s;if ( s==0 || s[0]==0 )
return 0;
for ( int i=0 ; *p && i<8 ; ++i, ++p ) {
if ( !iswxdigit(*p) )
return 0;
}while ( s<p ) {
Ret<<=4;
Ret+= htoi(*(s++));
}return Ret;
}bool wtoi64(wchar_t *String, unsigned long long *ll) {
const int BUFSIZE= 32; // 64*log(2)<20
wchar_t Buffer[BUFSIZE];
int i;
enum { cHex, cDec, cUnknown } Category= cUnknown;if ( String==0 || String[0]==0 )
return false;if ( String[0]==L’0′ && (String[1]==L’x’ || String[1]==L’X’) ) {
Category= cHex;
String+= 2;
}
else if ( String[0]==L’0′ && (String[1]==L’n’ || String[1]==L’N’) ) {
Category= cDec;
String+= 2;
}
const wchar_t *cp= String;
wchar_t *p= Buffer;for ( i=0 ; *cp && i<BUFSIZE ; ++i ) {
if ( iswdigit(*cp) )
*(p++)= *(cp++);
else if ( iswxdigit(*cp) ) {
if ( Category==cDec ) return false;
Category= cHex;
*(p++)= *(cp++);
}
else if ( *cp==L’`’ ) {
if ( Category==cDec ) return false;
++cp;
}
else
return false;
}
if ( i==BUFSIZE ) return false;if ( Category==cUnknown ) Category= cDec; ← ここで既定値が決まる。
*p= 0;if ( ll ) {
if ( Category==cDec )
*ll= _wtoi64(Buffer);
else {
if ( p-Buffer>=8 ) {
GET_LODWORD(*ll)= htoi(p-8); *(p-8)= 0;
GET_HIDWORD(*ll)= htoi(Buffer);
}
else {
GET_LODWORD(*ll)= htoi(Buffer);
GET_HIDWORD(*ll)= 0;
}
}
}return true;
}
ピンバック: [Win32] [C++] convert hexadecimal string into decimal integer « すなのかたまり