namespace std {
int stoi(const std::string& str, std::size_t* idx = nullptr, int base = 10); // (1)
int stoi(const std::wstring& str, std::size_t* idx = nullptr, int base = 10); // (2)
}
概要
文字列str
を数値として読み取って、int
型の値に変換する。
効果
パラメータstr
がstring
型であればstd::strtol(str.c_str(), &end, base)
、wstring
型であればstd::wcstol(str.c_str(), &end, base)
を呼び出して、その戻り値を返す。
パラメータidx
が非nullptr
の場合、変換に使用されなかった要素のインデックス(end - str.c_str()
)が格納される。
パラメータbase
は、整数文字列str
の基数を表す。デフォルトでは10
進数として文字列を整数に変換する。基数は2
から36
(36
含む)進数を指定できる。基数を0
とした場合は、文字列のプレフィックスから基数が自動的に選択される。自動的な選択のルールは、以下のようになる:
- 先頭が
0
:8
進数 - 先頭が
0x
もしくは0X
:16
進数
戻り値
変換して得られた数値が返される。
例外
- 数値への変換が行われなかった場合、
std::invalid_argument
が送出される。 - 以下の条件に合致した場合、
std::out_of_range
が送出される。
備考
errnoの扱い
- Visual C++ 11やGCC (libstdc++) 4.8.2では、この関数を呼び出すと
errno
の値が変更される。 - Clang (libc++) 3.3では、この関数の呼び出し前後で
errno
の値は変化しない。
グローバルロケールの影響
この関数は、setlocale()
関数により挙動が変化する。
strtol()
関数での文字列先頭の空白を読み飛ばす処理に、<cctype>
のisspace()
関数が使用されるためである。
例
#include <iostream>
#include <string>
int main()
{
// 10進法での変換
{
std::cout << "---- base = 10" << std::endl;
int x = std::stoi("10"); // std::stoi("10", nullptr, 10);
std::cout << x << std::endl;
int xw = std::stoi(L"11"); // std::stoi(L"11", nullptr, 10);
std::cout << xw << std::endl;
}
// 2進法での変換
{
std::cout << "---- base = 2" << std::endl;
int x = std::stoi("1001", nullptr, 2);
std::cout << x << std::endl;
int xw = std::stoi(L"01001", nullptr, 2); // 先頭に0が付いていてもよい
std::cout << xw << std::endl;
}
// 8進法での変換
{
std::cout << "---- base = 8" << std::endl;
int x = std::stoi("10", nullptr, 8);
std::cout << x << std::endl;
int xw = std::stoi(L"10", nullptr, 8);
std::cout << xw << std::endl;
}
// 16進法での変換
{
std::cout << "---- base = 16" << std::endl;
int x = std::stoi("10", nullptr, 16);
std::cout << x << std::endl;
int xw = std::stoi(L"11", nullptr, 16);
std::cout << xw << std::endl;
}
// 16進法での変換(プレフィックス付き)
{
int x = std::stoi("0x20", nullptr, 16);
std::cout << x << std::endl;
int xw = std::stoi(L"0x21", nullptr, 16);
std::cout << xw << std::endl;
}
// base = 0による10進法・8進法・16進法の自動判別
{
std::cout << "---- base = 0" << std::endl;
std::cout << std::stoi("100", nullptr, 0) << std::endl;
std::cout << std::stoi("0100", nullptr, 0) << std::endl;
std::cout << std::stoi("0x100", nullptr, 0) << std::endl;
std::cout << std::stoi(L"100", nullptr, 0) << std::endl;
std::cout << std::stoi(L"0100", nullptr, 0) << std::endl;
std::cout << std::stoi(L"0x100", nullptr, 0) << std::endl;
}
// 2番目の仮引数の使用例
{
std::cout << "---- use of idx parameter" << std::endl;
std::string s = "30%";
std::size_t i;
int x = std::stoi(s, &i);
std::cout << x << ' ' << s[i] << std::endl;
std::wstring ws = L"31%";
std::size_t wi;
int xw = std::stoi(ws, &wi);
std::cout << xw << ' ' << wi << std::endl;
}
// 文字列先頭に空白がある場合
{
std::cout << "---- space character before number" << std::endl;
std::cout << std::stoi(" -1") << std::endl;
std::cout << std::stoi(L" -2") << std::endl;
}
}
xxxxxxxxxx
#include <iostream>
#include <string>
int main()
{
// 10進法での変換
{
std::cout << "---- base = 10" << std::endl;
int x = std::stoi("10"); // std::stoi("10", nullptr, 10);
std::cout << x << std::endl;
int xw = std::stoi(L"11"); // std::stoi(L"11", nullptr, 10);
std::cout << xw << std::endl;
}
// 2進法での変換
{
出力
---- base = 10
10
11
---- base = 2
9
9
---- base = 8
8
8
---- base = 16
16
17
32
33
---- base = 0
100
64
256
100
64
256
---- use of idx parameter
30 %
31 2
---- space character before number
-1
-2
実装例
int stoi(const std::string& str, std::size_t* idx = nullptr, int base = 10) {
const char* p = str.c_str();
char* end;
errno = 0;
long x = std::strtol(p, &end, base);
if (p == end) {
throw std::invalid_argument("stoi");
}
if (errno == ERANGE || x < INT_MIN || x > INT_MAX) {
throw std::out_of_range("stoi");
}
if (idx != nullptr) {
*idx = static_cast<std::size_t>(end - p);
}
return static_cast<int>(x);
}
int stoi(const std::wstring& str, std::size_t* idx = nullptr, int base = 10) {
const wchar_t* p = str.c_str();
wchar_t* end;
errno = 0;
long x = std::wcstol(p, &end, base);
if (p == end) {
throw std::invalid_argument("stoi");
}
if (errno == ERANGE || x < INT_MIN || x > INT_MAX) {
throw std::out_of_range("stoi");
}
if (idx != nullptr) {
*idx = static_cast<std::size_t>(end - p);
}
return static_cast<int>(x);
}
バージョン
言語
- C++11
処理系
- Clang: ?
- GCC: ?
- ICC: ?
- Visual C++: 2010 ✅, 2012 ✅, 2013 ✅
関連リンク
C標準ライブラリに由来する関数
atoi
:stoi
はatoi
をstd::string
およびstd::wstring
に対応させたものと見なせる。strtol
,wcstol
:stoi
はstrtol
およびwcstol
をそれぞれstd::string
とstd::wstring
に対応させ、戻り値の型をint
に変更したものと見なせる。
ファミリー
- (
stoi
: この関数自身) stol
: 戻り値の型がlong
となったもの。stoll
: 戻り値の型がlong long
となったもの。stoul
: 戻り値の型がunsigned long
となったもの。stoull
: 戻り値の型がunsigned long long
となったもの。stof
: 戻り値の型がfloat
となったもの。stod
: 戻り値の型がdouble
となったもの。stold
: 戻り値の型がlong double
となったもの。