2進数や8進数、10進数、16進数で表記された文字列を、整数型の数値に変換する方法を解説します。
N進文字列から整数型への数値変換を実現する場合には、strtol関数やsscanf関数を用いた方法を取ることが一般的です。
- strtol関数(C言語)
- sscanf関数(C言語)
- atof関数(C言語 - 16進数のみ対応)
- std::stoi関数(C++ - std::string型からの変換)
strtol関数
strtol関数は文字列を数値に変換するための関数ですが、第三引数に基数を指定することが可能となっています。ここに変換したいN進数の基数を指定することで、N進表記の文字列から数値への変換が行えます。
long v = strtol("11", NULL, 2); // 3 ( 2進数)
long v = strtol("11", NULL, 8); // 9 ( 8進数)
long v = strtol("11", NULL, 10); // 11 (10進数)
long v = strtol("11", NULL, 16); // 17 (16進数)
strtol("011" , NULL, 8); // 9 ( 8進数) // 接頭辞`0`も可
strtol("0x11", NULL, 16); // 17 (16進数) // 接頭辞`0x`や`0X`も可
文字列内の数字列に基数を表す接頭辞(16進数を表す0x
, 0X
や8進数を表す0
)が付随されている場合には、第三引数を0
に指定することも可能です。
strtol("011" , NULL, 0); // 9 ( 8進数)
strtol("11" , NULL, 0); // 11 (10進数)
strtol("0x11", NULL, 0); // 17 (16進数)
strtol("0b11", NULL, 0); // 0 ( 2進数は非対応)
strtol("0011", NULL, 0); // 9 ( 2進数は非対応)
基数を表す接頭辞の考慮は、16進表記の場合に限り、strtod関数でも行われます。また同等の変換は# atof関数でも行われます。
double v = strtod("0x11", NULL); // 17 (16進数)
double v = strtod("011", NULL); // 11 (10進数) => 8進数による変換には非対応
sscanf関数
sscanf関数では、8進整数と16進整数の変換指定を行うことができます。8進文字列からの変換を表す際には%o
を指定し、16進文字列では%x
を指定します。
unsigned int u;
/* 16進数 */
sscanf("11" , "%x", &u); // u == 17
sscanf("0x11", "%x", &u); // u == 17
/* 8進数 */
sscanf("11" , "%o", &u); // u == 9
sscanf("011", "%o", &u); // u == 9
/* 10進数 */
sscanf("11", "%u", &u); // u == 11
2進数の変換には対応していません。10進数については一般的な%d
や%u
を用います。
なお、8進整数と16進整数の変換指定子%o
,%x
を用いる場合には、sscanf関数の実引数として符号無し整数へのポインタを指定する必要があります。上記の例ではunsigned int
型を利用しています。
大きな値を変換する場合には、長さ修飾子としてlong型を表すl
やlong long型を表すll
を指定する必要があります。以下の例では、unsigned long
型相当の16進文字列を変換するために、変換指定子として%lx
を指定しています。
unsigned long ul;
sscanf("FFFFFFFFFFFFFFFF", "%lx", &ul);
// ul == ULONG_MAX
FFFFFFFFFFFFFFFF
のデータ幅は64bit長となっていますが、long型が32bitで表現されているような環境では、全てのデータを変換しきれない場合があります。その場合は、long long型による変換を検討してみると良いでしょう。
atof関数
atof関数は、数字列の先頭が0x
または0X
で始まる場合に、数字列を16進数として変換します。8進数としての変換には対応していないため注意が必要です。また戻り値型はdouble型となります。
double v = atof("0x11"); // 17 (16進数として変換)
double v = atof("011"); // 11 (10進数として変換、8進数による変換には非対応)
std::stoi関数
C++の文字列型std::string
から変換する場合にはstd::stoi
関数を用いることができます。stoi関数の第三引数に基数を指定します。
int v = std::stoi("11", nullptr, 2); // 2 ( 2進数)
int v = std::stoi("11", nullptr, 8); // 9 ( 8進数)
int v = std::stoi("11", nullptr, 16); // 17 (16進数)
double v = std::stod("0x10"); // 16
stoi関数stod関数のより詳しい説明については以下の記事が参考になります。