n進文字列と整数値の相互変換を紹介します。(戻る)
アルゴリズム
ここではn進数の文字列と整数値の相互変換する関数を3つ紹介してます。
文字列から整数値に変換する場合は、文字列の先頭から[0]~[9]、[A]~[Z]、[a]~[z]の文字を解読してきます。
桁上がりは引数で指定した nRadix の値をそのまま掛け算します。
整数値から文字列に変換する場合は、整数値の下位桁から[0]~[35]の余りを解読してきます。
余りは普通に36で割って求めます。(%演算)
この余りから[0]~[9]、[A]~[Z]、[a]~[z]の文字に変換して文字列バッファ(lpBuff)にコピーします。
しかし、このままでは文字列が左右反転してるので戻すために左右並びを反転させます。
このときに出力桁数分だけスペース文字などを文字列バッファ(lpBuff)にコピーします。
こうすることで文字列バッファ(lpBuff)の先頭に出力桁数に見合うスペース文字で埋められます。
なお、スペース文字の代わりに[0]の文字で埋めたり、接頭語(0b、0o、0d、0x)もコピーするように改良も可能です。
接頭語(0b、0o、0d、0x)を出力するときには[x][0]の順にコピーしたり、出力桁数から2文字分だけ引いた残りが
スペース文字(ゼロ文字)で埋める出力桁数になることに気をつけましょう。
今回は接頭語(0b、0o、0d、0x)は出力しません。
//------------------------------------------------ // 関数のプロトタイプ宣言 //------------------------------------------------ extern UINT funcStrToInt( LPCTSTR lpString, UINT nRadix ); extern UINT funcStrToIntEx( LPCTSTR lpString, UINT nRadix ); extern LPTSTR funcIntToStr( LPTSTR lpBuff, UINT nValue, LONG nRadix ); extern LPTSTR funcIntToStrEx( LPTSTR lpBuff, UINT nValue, LONG nWidth, TCHAR tcSpace, LONG nRadix );
サンプル
//------------------------------------------------------------------------------ // n進文字列と整数値の相互変換 //------------------------------------------------------------------------------ #include <stdio.h> #include <tchar.h> #include <ctype.h> #include <wctype.h> #include <locale.h> #include <Windows.h> //------------------------------------------------ // break 付きのキーワード //------------------------------------------------ #define CASE break;case #define DEFAULT break;default //------------------------------------------------ // n進文字列から整数値に変換 //------------------------------------------------ extern UINT funcStrToInt( LPCTSTR lpString, UINT nRadix ) { UINT nValue; UINT nRet; for ( nRet = 0 ; _istalnum(*lpString) ; lpString++ ){ if ( _istdigit(*lpString) ){ nValue = (*lpString - TEXT('0')); } else if ( _istupper(*lpString) ){ nValue = (*lpString - TEXT('A') + 10); } else{ nValue = (*lpString - TEXT('a') + 10); } if ( nValue >= nRadix ){ break; } nRet *= nRadix; nRet += nValue; } return nRet; } //------------------------------------------------ // 接頭語付き文字列から整数値に変換 //------------------------------------------------ extern UINT funcStrToIntEx( LPCTSTR lpString, UINT nRadix ) { if ( nRadix == 0 ){ if ( *lpString == TEXT('0') ){ switch ( *(++lpString) ){ CASE TEXT('b'): nRadix = 2; CASE TEXT('o'): nRadix = 8; CASE TEXT('d'): nRadix = 10; CASE TEXT('x'): nRadix = 16; DEFAULT: return 0; } return funcStrToInt( (lpString + 1), nRadix ); } return funcStrToInt( lpString, 10 ); } return funcStrToInt( lpString, nRadix ); } /* 0b01 0o01234567 0d0123456789 0x0123456789ABCDEF 123456789 */ //------------------------------------------------ // 文字列の左右並びを反転 //------------------------------------------------ static VOID funcStrReverse( LPTSTR lpHead, LPTSTR lpTail ) { TCHAR tcSwap[ 1 ]; for ( *lpTail-- = TEXT('\0') ; lpHead < lpTail ; lpHead++, lpTail-- ){ tcSwap[ 0 ] = lpHead[ 0 ]; lpHead[ 0 ] = lpTail[ 0 ]; lpTail[ 0 ] = tcSwap[ 0 ]; } } //------------------------------------------------ // 整数値からn進文字列に変換 //------------------------------------------------ extern LPTSTR funcIntToStr( LPTSTR lpBuff, UINT nValue, LONG nRadix ) { LPTSTR lpTable; LPTSTR lpTail; if ( nValue == 0 ){ lpBuff[0] = TEXT('0'); lpBuff[1] = TEXT('\0'); return lpBuff; } if ( nRadix < 0 ){ nRadix = -nRadix; lpTable = TEXT("0123456789abcdefghijklmnopqrstuvwxyz"); } else{ lpTable = TEXT("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"); } for ( lpTail = lpBuff ; nValue ; nValue /= nRadix ){ *lpTail++ = lpTable[ nValue % nRadix ]; } funcStrReverse( lpBuff, lpTail ); return lpBuff; } //------------------------------------------------ // 文字列の左右並びを反転 //------------------------------------------------ static VOID funcStrReverseEx( LPTSTR lpHead, LPTSTR lpTail, LONG nWidth, TCHAR tcSpace ) { TCHAR tcSwap[ 1 ]; while ( nWidth > 0 ){ nWidth--; *lpTail++ = tcSpace; } for ( *lpTail-- = TEXT('\0') ; lpHead < lpTail ; lpHead++, lpTail-- ){ tcSwap[ 0 ] = lpHead[ 0 ]; lpHead[ 0 ] = lpTail[ 0 ]; lpTail[ 0 ] = tcSwap[ 0 ]; } } //------------------------------------------------ // 整数値からn桁n進文字列に変換 //------------------------------------------------ extern LPTSTR funcIntToStrEx( LPTSTR lpBuff, UINT nValue, LONG nWidth, TCHAR tcSpace, LONG nRadix ) { LPTSTR lpTable; LPTSTR lpTail = lpBuff; if ( nRadix < 0 ){ nRadix = -nRadix; lpTable = TEXT("0123456789abcdefghijklmnopqrstuvwxyz"); } else{ lpTable = TEXT("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"); } if ( nValue == 0 ){ nWidth--; *lpTail++ = TEXT('0'); } else for ( ; nValue ; nValue /= nRadix ){ nWidth--; *lpTail++ = lpTable[ nValue % nRadix ]; } funcStrReverseEx( lpBuff, lpTail, nWidth, tcSpace ); return lpBuff; } //------------------------------------------------ // メイン関数 //------------------------------------------------ int _tmain( void ) { // 接頭語なし LPCTSTR lpBin1 = TEXT("111010110111100110100010101"); LPCTSTR lpOct1 = TEXT("726746425"); LPCTSTR lpDec1 = TEXT("123456789"); LPCTSTR lpHex1 = TEXT("75BCD15"); // 接頭語あり LPCTSTR lpBin2 = TEXT("0b111010110111100110100010101"); LPCTSTR lpOct2 = TEXT("0o726746425"); LPCTSTR lpDec2 = TEXT("0d123456789"); LPCTSTR lpHex2 = TEXT("0x75BCD15"); // その他 TCHAR szBuff[ 256 ]; LONG nValue; LONG nWidth = 8; TCHAR tcSpace = TEXT('0'); // ロケールの設定 _tsetlocale( LC_ALL, TEXT("") ); // 文字列→整数値 _tprintf( TEXT("\n// 接頭語なし\n") ); _tprintf( TEXT("%-30s = %ld\n"), lpBin1, funcStrToInt(lpBin1,2) ); _tprintf( TEXT("%-30s = %ld\n"), lpOct1, funcStrToInt(lpOct1,8) ); _tprintf( TEXT("%-30s = %ld\n"), lpDec1, funcStrToInt(lpDec1,10) ); _tprintf( TEXT("%-30s = %ld\n"), lpHex1, funcStrToInt(lpHex1,16) ); _tprintf( TEXT("\n// 接頭語あり\n") ); _tprintf( TEXT("%-30s = %ld\n"), lpBin2, funcStrToIntEx(lpBin2,0) ); _tprintf( TEXT("%-30s = %ld\n"), lpOct2, funcStrToIntEx(lpOct2,0) ); _tprintf( TEXT("%-30s = %ld\n"), lpDec2, funcStrToIntEx(lpDec2,0) ); _tprintf( TEXT("%-30s = %ld\n"), lpHex2, funcStrToIntEx(lpHex2,0) ); // 整数値→文字列 _tprintf( TEXT("\n// 整数値からn進文字列に変換(大文字)\n") ); for ( nValue = 0 ; nValue < 32 ; nValue++ ){ _tprintf( TEXT("%2ld = [%s]\n"), nValue, funcIntToStr(szBuff,nValue,+16) ); } _tprintf( TEXT("\n// 整数値からn進文字列に変換(小文字)\n") ); for ( nValue = 0 ; nValue < 32 ; nValue++ ){ _tprintf( TEXT("%2ld = [%s]\n"), nValue, funcIntToStr(szBuff,nValue,-16) ); } // 整数値→文字列(n桁) _tprintf( TEXT("\n// 整数値からn進文字列に変換(大文字)\n") ); for ( nValue = 0 ; nValue < 32 ; nValue++ ){ _tprintf( TEXT("%2ld = [%s]\n"), nValue, funcIntToStrEx(szBuff,nValue,nWidth,tcSpace,+16) ); } _tprintf( TEXT("\n// 整数値からn進文字列に変換(小文字)\n") ); for ( nValue = 0 ; nValue < 32 ; nValue++ ){ _tprintf( TEXT("%2ld = [%s]\n"), nValue, funcIntToStrEx(szBuff,nValue,nWidth,tcSpace,-16) ); } return 0; } //------------------------------------------------------------------------------ // End of funcStrToInt.cpp //------------------------------------------------------------------------------
実行結果
// 接頭語なし 111010110111100110100010101 = 123456789 726746425 = 123456789 123456789 = 123456789 75BCD15 = 123456789 // 接頭語あり 0b111010110111100110100010101 = 123456789 0o726746425 = 123456789 0d123456789 = 123456789 0x75BCD15 = 123456789 // 整数値からn進文字列に変換(大文字) 0 = [0] 1 = [1] 2 = [2] 3 = [3] 4 = [4] 5 = [5] 6 = [6] 7 = [7] 8 = [8] 9 = [9] 10 = [A] 11 = [B] 12 = [C] 13 = [D] 14 = [E] 15 = [F] 16 = [10] 17 = [11] 18 = [12] 19 = [13] 20 = [14] 21 = [15] 22 = [16] 23 = [17] 24 = [18] 25 = [19] 26 = [1A] 27 = [1B] 28 = [1C] 29 = [1D] 30 = [1E] 31 = [1F] // 整数値からn進文字列に変換(小文字) 0 = [0] 1 = [1] 2 = [2] 3 = [3] 4 = [4] 5 = [5] 6 = [6] 7 = [7] 8 = [8] 9 = [9] 10 = [a] 11 = [b] 12 = [c] 13 = [d] 14 = [e] 15 = [f] 16 = [10] 17 = [11] 18 = [12] 19 = [13] 20 = [14] 21 = [15] 22 = [16] 23 = [17] 24 = [18] 25 = [19] 26 = [1a] 27 = [1b] 28 = [1c] 29 = [1d] 30 = [1e] 31 = [1f] // 整数値からn進文字列に変換(大文字) 0 = [00000000] 1 = [00000001] 2 = [00000002] 3 = [00000003] 4 = [00000004] 5 = [00000005] 6 = [00000006] 7 = [00000007] 8 = [00000008] 9 = [00000009] 10 = [0000000A] 11 = [0000000B] 12 = [0000000C] 13 = [0000000D] 14 = [0000000E] 15 = [0000000F] 16 = [00000010] 17 = [00000011] 18 = [00000012] 19 = [00000013] 20 = [00000014] 21 = [00000015] 22 = [00000016] 23 = [00000017] 24 = [00000018] 25 = [00000019] 26 = [0000001A] 27 = [0000001B] 28 = [0000001C] 29 = [0000001D] 30 = [0000001E] 31 = [0000001F] // 整数値からn進文字列に変換(小文字) 0 = [00000000] 1 = [00000001] 2 = [00000002] 3 = [00000003] 4 = [00000004] 5 = [00000005] 6 = [00000006] 7 = [00000007] 8 = [00000008] 9 = [00000009] 10 = [0000000a] 11 = [0000000b] 12 = [0000000c] 13 = [0000000d] 14 = [0000000e] 15 = [0000000f] 16 = [00000010] 17 = [00000011] 18 = [00000012] 19 = [00000013] 20 = [00000014] 21 = [00000015] 22 = [00000016] 23 = [00000017] 24 = [00000018] 25 = [00000019] 26 = [0000001a] 27 = [0000001b] 28 = [0000001c] 29 = [0000001d] 30 = [0000001e] 31 = [0000001f]
- funcStrToInt 関数は接頭語(0b、0o、0d、0x)を解釈しないので付けると 0 になります。(仕様)
- funcStrToIntEx 関数は接頭語(0b、0o、0d、0x)を解釈するので nRadix は 0 にします。
なお nRadix が 0 以外では接頭語(0b、0o、0d、0x)を解釈しません。(注意) - funcIntToStr 関数は単純に整数値から2進文字列に変換してます。
なお nRadix にマイナス値を指定すると小文字で変換されます。 - funcIntToStrEx 関数は出力桁数と出力文字を指定して2進文字列に変換してます。
実はこの関数が本命で funcIntToStr 関数は理解しやすいように載せたものです。
※コメント投稿者のブログIDはブログ作成者のみに通知されます