8進文字列と整数値の相互変換を紹介します。(戻る)
アルゴリズム
ここでは8進数の文字列と整数値の相互変換する関数を3つ紹介してます。
文字列から整数値に変換する場合は、文字列の先頭から[0]~[7]の文字を解読してきます。
桁上がりは8倍する代わりに3ビットだけ左シフトすることで同じ効果を行ってます。
整数値から文字列に変換する場合は、整数値の下位桁から[0]~[7]の余りを解読してきます。
余りを求めるのに8で割る代わりに3ビットのビット論理積を使ってます。(ちょっとだけ高速)
この余りから[0]~[7]の文字に変換して文字列バッファ(lpBuff)にコピーします。
しかし、このままでは文字列が左右反転してるので戻すために左右並びを反転させます。
このときに出力桁数分だけスペース文字などを文字列バッファ(lpBuff)にコピーします。
こうすることで文字列バッファ(lpBuff)の先頭に出力桁数に見合うスペース文字で埋められます。
なお、スペース文字の代わりに[0]の文字で埋めたり、接頭語(0o)もコピーするように改良も可能です。
接頭語(0o)を出力するときには[o][0]の順にコピーしたり、出力桁数から2文字分だけ引いた残りが
スペース文字(ゼロ文字)で埋める出力桁数になることに気をつけましょう。
今回は接頭語(0o)は出力しません。
//------------------------------------------------ // 関数のプロトタイプ宣言 //------------------------------------------------ extern UINT funcOctToInt( LPCTSTR lpString ); extern LPTSTR funcIntToOct( LPTSTR lpBuff, UINT nValue ); extern LPTSTR funcIntToOctEx( LPTSTR lpBuff, UINT nValue, LONG nWidth, TCHAR tcSpace );
サンプル
//------------------------------------------------------------------------------ // 8進文字列と整数値の相互変換 //------------------------------------------------------------------------------ #include <stdio.h> #include <tchar.h> #include <locale.h> #include <Windows.h> //------------------------------------------------ // マクロ関数 //------------------------------------------------ #define funcStrIsOct(s) ((TEXT('0')<=(s)[0]) && ((s)[0]<=TEXT('7'))) //------------------------------------------------ // 8進文字列から整数値に変換 //------------------------------------------------ extern UINT funcOctToInt( LPCTSTR lpString ) { UINT nRet; for ( nRet = 0 ; funcStrIsOct(lpString) ; lpString++ ){ nRet <<= 3; nRet |= (*lpString - TEXT('0')); } return nRet; } //------------------------------------------------ // 文字列の左右並びを反転 //------------------------------------------------ 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 ]; } } //------------------------------------------------ // 整数値から8進文字列に変換 //------------------------------------------------ extern LPTSTR funcIntToOct( LPTSTR lpBuff, UINT nValue ) { LPTSTR lpTail; if ( nValue == 0 ){ lpBuff[0] = TEXT('0'); lpBuff[1] = TEXT('\0'); return lpBuff; } for ( lpTail = lpBuff ; nValue ; nValue >>= 3 ){ *lpTail++ = ((nValue & 0x7) + TEXT('0')); } 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桁8進文字列に変換 //------------------------------------------------ extern LPTSTR funcIntToOctEx( LPTSTR lpBuff, UINT nValue, LONG nWidth, TCHAR tcSpace ) { LPTSTR lpTail = lpBuff; if ( nValue == 0 ){ nWidth--; *lpTail++ = TEXT('0'); } else for ( ; nValue ; nValue >>= 3 ){ nWidth--; *lpTail++ = ((nValue & 0x7) + TEXT('0')); } funcStrReverseEx( lpBuff, lpTail, nWidth, tcSpace ); return lpBuff; } //------------------------------------------------ // メイン関数 //------------------------------------------------ int _tmain( void ) { LPCTSTR lpOct1 = TEXT("726746425"); LPCTSTR lpOct2 = TEXT("0o726746425"); TCHAR szBuff[ 256 ]; LONG nValue; LONG nWidth = 8; TCHAR tcSpace = TEXT('0'); // ロケールの設定 _tsetlocale( LC_ALL, TEXT("") ); // 文字列→整数値 _tprintf( TEXT("\n// 8進文字列から整数値に変換\n") ); _tprintf( TEXT("%12s = %ld\n"), lpOct1, funcOctToInt(lpOct1) ); _tprintf( TEXT("%12s = %ld\n"), lpOct2, funcOctToInt(lpOct2) ); // 整数値→文字列 _tprintf( TEXT("\n// 整数値から8進文字列に変換\n") ); for ( nValue = 0 ; nValue < 32 ; nValue++ ){ _tprintf( TEXT("%2ld = [%s]\n"), nValue, funcIntToOct(szBuff,nValue) ); } // 整数値→文字列(n桁) _tprintf( TEXT("\n// 整数値から8進文字列に変換\n") ); for ( nValue = 0 ; nValue < 32 ; nValue++ ){ _tprintf( TEXT("%2ld = [%s]\n"), nValue, funcIntToOctEx(szBuff,nValue,nWidth,tcSpace) ); } return 0; } //------------------------------------------------------------------------------ // End of funcOctToInt.cpp //------------------------------------------------------------------------------
実行結果
// 8進文字列から整数値に変換 726746425 = 123456789 0o726746425 = 0 // 整数値から8進文字列に変換 0 = [0] 1 = [1] 2 = [2] 3 = [3] 4 = [4] 5 = [5] 6 = [6] 7 = [7] 8 = [10] 9 = [11] 10 = [12] 11 = [13] 12 = [14] 13 = [15] 14 = [16] 15 = [17] 16 = [20] 17 = [21] 18 = [22] 19 = [23] 20 = [24] 21 = [25] 22 = [26] 23 = [27] 24 = [30] 25 = [31] 26 = [32] 27 = [33] 28 = [34] 29 = [35] 30 = [36] 31 = [37] // 整数値から8進文字列に変換 0 = [00000000] 1 = [00000001] 2 = [00000002] 3 = [00000003] 4 = [00000004] 5 = [00000005] 6 = [00000006] 7 = [00000007] 8 = [00000010] 9 = [00000011] 10 = [00000012] 11 = [00000013] 12 = [00000014] 13 = [00000015] 14 = [00000016] 15 = [00000017] 16 = [00000020] 17 = [00000021] 18 = [00000022] 19 = [00000023] 20 = [00000024] 21 = [00000025] 22 = [00000026] 23 = [00000027] 24 = [00000030] 25 = [00000031] 26 = [00000032] 27 = [00000033] 28 = [00000034] 29 = [00000035] 30 = [00000036] 31 = [00000037]
- funcOctToInt 関数は接頭語(0o)を解釈しないので付けると 0 になります。(仕様)
- funcIntToOct 関数は単純に整数値から8進文字列に変換してます。
- funcIntToOctEx 関数は出力桁数と出力文字を指定して8進文字列に変換してます。
実はこの関数が本命で funcIntToOct 関数は理解しやすいように載せたものです。
※コメント投稿者のブログIDはブログ作成者のみに通知されます