【C言語/C++】2進数 8進数 10進数 16進数 文字列を数値に変換する方法

2進数や8進数、10進数、16進数で表記された文字列を、整数型の数値に変換する方法を解説します。

N進文字列から整数型への数値変換を実現する場合には、strtol関数やsscanf関数を用いた方法を取ることが一般的です。

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関数のより詳しい説明については以下の記事が参考になります。

【C++】std::stoi関数

広告