std::string → 数値
文字列型std::string
をint
やdouble
等の数値型に変換する方法です。
int型への変換はstd::stoi
関数、double型の変換はstd::stod
を用います。
std::string str = "3.14";
int i = std::stoi(str); // 3
double d = std::stod(str); // 3.14
long型、float型への変換やstd::sto~
系関数の詳細については後半で解説します(# std::sto~系関数)。
文字列(配列)→ 数値
C言語スタイルの文字列(char[]
, const char*
)を整数値や浮動小数点数に変換する場合は、C言語由来の関数を用いる必要があります。
// #include <cstdlib> // std::atoi, std::strtol
// #include <cstdio> // std::sscanf
std::string s = "99yen";
// atoi関数による変換
int i = std::atoi(s.c_str()); // 99 == i
// strtol関数による変換
long l = std::strtol(s.c_str(), nullptr, 10); // 99 == l
// sscanf関数による変換
int n = std::sscanf(s.c_str(), "%d", &i); // 99 == i, 1 == n
各関数の詳しい説明や注意点については、以下のページを参考にしてください。
参考: 【C言語】文字列を数値に変換する方法【危険なatoi関数、厳格なstrtol関数、怠慢なsscanf】
std::sto~系関数
目次
- 変換関数一覧(int, long, float, double, 等々)
- 関数の概要
- 第二引数 ─ インデックスの取得
- 第三引数 ─ 基数の指定
- 例外
- 特殊な形式の数値を変換する
変換関数一覧
long
型やfloat
型用の専用関数も用意されています。
型 | 対応する関数 |
---|---|
int | std::stoi |
long | std::stol |
unsigned long | std::stoul |
long long | std::stoll |
unsigned long long | std::stoull |
float | std::stof |
double | std::stod |
long double | std::stold |
関数の概要
// #include <string>
int stoi(const std::string& str, size_t* idx = 0, int base = 10);
double stod(const std::string& str, size_t* idx = 0);
戻り値 | 変換後の値 |
---|---|
第一引数 | 読み取り文字列 |
第二引数 | 変換完了後の読み取り位置 |
第三引数 | 基数 |
例外 | std::invalid_argument, std::out_of_range |
参考 | 特殊な形式の数値を変換する |
第二引数 ─ インデックスの取得
第二引数にsize_t
型のポインタを渡すことで、文字列中の「変換完了位置+1」のインデックスを取得することが可能です。
size_t index;
std::stod("3.1%", &index);
printf("%ld", index); // 3
printf("%c", "3.1%"[index]); // '%'
std::stod(" 1e4", &index);
printf("%ld", index); // 4
printf("%c", " 1e4"[index]); // '\0' (終端文字)
第三引数 ─ 基数の指定
第三引数に基数を指定することが可能です。
2
を指定すれば2進数、16
を指定すれば16進数として文字列の変換作業が行われます。
std::stoi("1000", nullptr, 2); // 8 (0b1000 2進数)
std::stoi("10", nullptr, 8); // 8 (010 8進数)
std::stoi("10", nullptr, 16); // 16 (0x10 16進数)
std::stoi("0xF", nullptr, 16); // 15 (0x0F)
std::stoi("F", nullptr, 16); // 15 (0x0F)
std::stoi("F", nullptr, 2); // 例外発生:std::invalid_argument: stoi: no conversion
第三引数に0
が指定された場合は基数の自動判定が行われます。
std::stoi("010", nullptr, 0); // 8 ( 8進数)
std::stoi("0xf", nullptr, 0); // 15 (16進数)
例外
std::invalid_argument
文字列を数値に変換できなかった場合にはstd::invalid_argument
例外が発生し、プログラムは異常終了します。C言語のatoi関数とは挙動が異なるため注意が必要です。
// 実行時エラー: libc++abi.dylib: terminating with uncaught exception of type std::invalid_argument: stoi: no conversion
std::stoi("mad");
std::atoi("mad"); // エラーにならない。戻り値は0
以下の方法で例外を捕捉します。
try {
std::stoi("mad");
} catch (const std::invalid_argument& e) {
// 変換失敗時の処理
std::cout << e.what(); // "stoi: no conversion"
std::cout << "変換に失敗しました";
}
std::out_of_range
数値変換中に、値のオーバーフローまたはアンダーフローが発生した場合にはstd::out_of_range
例外が発生します。
// 実行時エラー: terminating with uncaught exception of type std::out_of_range: stoi: out of range
std::stoi("2147483648"); // 2147483647 == INT_MAX (int型の最大値)
try {
std::stoi("2147483648");
} catch (const std::out_of_range& e) {
puts(e.what()); // "stoi: out of range"
puts("オーバーフローが発生しました");
}
オーバーフローとアンダーフローの正確な判別を行いたい場合には、C言語のstrto~
系関数を用いる必要があります。
参考: 【C言語】strtol関数
特殊な形式の数値を変換する
16進数や指数表記の数字を変換することも可能です。また文字列中の先頭空白文字は変換時に無視されます。
std::stoi("9kg"); // 9 (末尾文字は無視される)
std::stod("\t\n 8"); // 8 (先頭の空白は無視される)
std::stod("1e3"); // 1000 (指数表記からの変換)
std::stod("0x02"); // 2 (16進数からの変換)