【C言語】atoi関数|ato関数群(atoi, atol, atoll, atof)完全解説

atoi関数

atoi関数は文字列を整数型の数値に変換する関数です。文字列中の最初に出現する整数を数値に変換します。

int i = atoi("9");     // i == 9
int i = atoi("99yen"); // i == 99
int i = atoi("  8");   // i == 8
int i = atoi("76 5");  // i == 76
int i = atoi("abc");   // i == 0

仕様

#include <stdlib.h>
int atoi(const char *nptr);
第一引数const char *nptr変換する文字列
戻り値int変換後の数値

atoi関数は第一引数に指定された文字列をint型の整数値に変換して返します。変換できない文字列だった場合には値0を返します。変換する値が表現可能な値の範囲外であった場合、戻り値は処理系によって異なった値となります。またerrnoの書き換えについても処理系依存となっています。

エラーが発生した場合の動作を除けば、atoi関数は(int)strtol(nptr, (char **)NULL, 10)と同等の処理が行われることになります。

なお、atoi関数には、変換値のオーバーフロー/アンダーフローを考慮した厳格な変換やエラー制御が行えないという問題があります。そのため場合によっては、より細かな制御が可能なstrtol関数の利用が必要となります。

参考: strtol関数|strto関数群(strtol, strtoul, strtoq, strtouq)

空白の扱い

変換文字列中の先頭の連続する空白類文字(スペース、タブ、改行文字等を含む)は無視されます。対象の空白類文字はisspace関数の既定に沿ったものとなります(' ', '\t', '\n', '\r', '\v', '\f')。

int i = atoi("\t\n\r\v\f 9"); // i == 9

エラーが発生した場合の挙動

変換対象の値が表現可能な値の範囲外であった場合(いわゆるオーバーフローやアンダーフローが発生しうるケース)、戻り値やerrnoの値は未定義動作により処理系依存の結果となる点に注意が必要です。

atoi関数が内部的にstrtol関数を呼び出すような処理系を用いている場合は、errnoへの代入値はstrtolのそれと同等となります。ただし戻り値については、strtolの戻り値型であるlong型からint型へのキャストが発生する都合上、不定な値となります。また文字列はlong型の範囲内で解析されるため、int型のオーバーフローとアンダーフローによるエラーを検知することはできません。
// int atoi(const char *nptr) { return (int)strtol(nptr, (char **)NULL, 10); }

// INT_MAX == 2147483647
printf("%d, %d", atoi(" 2147483647"), errno); //  2147483647, 0
printf("%d, %d", atoi(" 2147483648"), errno); // -2147483648, 0
printf("%d, %d", atoi("-2147483649"), errno); //  2147483647, 0
// LONG_MAX == 9223372036854775807, LONG_MIN == -9223372036854775808
printf("%d, %d", atoi("9223372036854775806"), errno); // -2, 0
printf("%d, %d", atoi("9223372036854775807"), errno); // -1, 0
printf("%d, %d", atoi("9223372036854775808"), errno); // -1, 34 (ERANGE - Result too large)
printf("%d, %d", atoi("-9223372036854775809"), errno); // 0, 34 (ERANGE - Result too large)

変換不可能な文字列だった場合にはerrnoに対してEINVALがセットされる場合があります。

// Clang/LLVMコンパイラ
printf("%d, %d\n", atoi("yen"), errno); // 0,  22 (EINVAL - Invalid argument) 

戻り値に関してはstrtol関数の既定により0となります。

atol関数

atol関数はstrtol(nptr, (char **)NULL, 10)と同等の処理が行われること以外は# atoi関数と共通です。

#include <stdlib.h>
long atol(const char *nptr);

atoll関数

atoll関数はstrtoll(nptr, (char **)NULL, 10)と同等の処理が行われること以外は# atoi関数と共通です。

#include <stdlib.h>
long long atoll(const char *nptr);

atof関数

atof関数はstrtod(nptr, (char **)NULL)と同等の処理が行われること以外は# atoi関数と共通です。

#include <stdlib.h>
double atof(const char *nptr);
double f = atof("3.14");
printf("%f\n", f); // 3.140000

なお、atof関数はstrtodの既定により、より柔軟な変換が行えます。

atof("0x11"); // 17   (16進数として変換)
atof("1e3");  // 1000 (指数表記からの変換)
atof("nan");  // nan  (非数)

広告