@@ -10,34 +10,31 @@ namespace std {
1010```
1111
1212## 概要
13- 文字列`nptr`を`long`型の整数に変換する。変換時には `base`で指定された基数に従って解釈される。
13+ 文字列`nptr`を`long`型の整数に変換する。文字列は `base`で指定された基数に従って解釈される。
1414
1515`endptr`が非`nullptr`の場合、変換が終了した位置の文字へのポインタがそこに格納される。
1616
1717基数`base`は 2~36 または 0 の値を取る。
1818
1919`base`が0の場合
20+ - 文字列の先頭が`0x`、`0X`は16進数
2021- 文字列の先頭が`0`の場合は8進数
21- - 先頭が`0x`、`0X`は16進数
22- - その他の場合は10進数として変換される。
22+ - その他の場合は10進数として変換する。
2323
2424変換は次のように行われる
25- - 先頭の空白文字は最初の非空白文字から変換される 。
25+ - 先頭が空白文字の場合、最初の非空白文字から変換される 。
2626- `+`または`-`が先頭にある場合は、符号として解釈される。
27+ - 基数が 16 または 0 の場合`0x`または`0X`をスキップする
2728- その後の文字列を、指定された`base`に基づいて整数値に変換する。
28-
29+ - 各桁は、`0`〜`9`をその値、`a`〜`z`および`A`〜`Z`を10〜35として扱う。
2930
3031## 戻り値
3132- 変換可能ならば変換後の数値。
32-
3333- 変換後の数値が`long`の範囲外の場合、`LONG_MAX`または `LONG_MIN`。
34-
3534- 変換不可能なら`0`を返す。
3635
3736## 備考
38- この関数はスレッドセーフである。
39-
40-
37+ - 数値が `long` の範囲を超えるときは `errno` に `ERANGE` が設定される。
4138
4239## 例
4340```cpp example
@@ -46,32 +43,51 @@ namespace std {
4643#include <cerrno>
4744#include <climits>
4845
49- int main() {
50- const char* str = " -0x2Fabc";
51-
52- errno = 0;
53- long result1 = std::strtol(str, nullptr, 0); // 自動判別
54- std::cout << "変換結果(基数0): " << result1 << std::endl;
55-
46+ void convert_and_print(const char* str, int base) {
5647 errno = 0;
57- long result2 = std::strtol(str, nullptr, 10); // 10進数として解釈
58- std::cout << "変換結果(基数10): " << result2 << std::endl;
48+ char* end = nullptr;
49+ long result = std::strtol(str, &end, base);
50+
51+ std::cout << "基数" << base << "での変換結果: " << result << std::endl;
52+ if (str == end) {
53+ std::cout << "変換不可" << std::endl;
54+ } else if (errno == ERANGE) {
55+ std::cout << " → 変換結果が範囲外" << std::endl;
56+ }
57+ if (*end != '\0') {
58+ std::cout << "未変換部分: \"" << end << "\"" << std::endl;
59+ }
60+ std::cout << std::endl;
61+ }
5962
60- errno = 0;
61- long result3 = std::strtol(str, nullptr, 36); // 36進数として解釈
62- std::cout << "変換結果(基数36): " << result3 << std::endl;
63+ int main() {
64+ const char* str = " -0x2Fabc";
65+ convert_and_print(str, 0); // 自動判別
66+ std::cout << std::endl;
67+ convert_and_print(str, 10); // 10進数
68+ convert_and_print(str, 36); // 36進数
6369
6470 return 0;
6571}
72+
6673```
6774### 出力
6875```
69- 変換結果(基数0): -195260
70- 変換結果(基数10): 0
71- 変換結果(基数36): -1999456248
76+ 基数0での変換結果: -195260
77+
78+ 基数10での変換結果: 0
79+ 未変換部分: "x2Fabc"
80+
81+ 基数36での変換結果: -1999456248
82+
7283```
7384
7485## 関連項目
7586- [ ` strtoll ` ] ( strtoll.md.nolink ) : 文字列を、基数を指定して` long long ` 型に変換する
7687- [ ` strtoul ` ] ( strtoul.md.nolink ) : 文字列を、基数を指定して` unsigned long ` 型に変換する
7788- [ ` strtoull ` ] ( strtoull.md.nolink ) : 文字列を、基数を指定して` unsigned long long ` 型に変換する
89+ - [ ` std::stol ` ] ( /reference/string/stol.md ) : 文字列から` long ` 型への変換
90+ - [ ` <charconv> ` ヘッダ] ( /reference/charconv.md ) : 高速な文字列 ⇔ 数値変換
91+
92+ ## 参考文献
93+ - Qiita: [ Cのstrtolの使い方とendptrの活用例(@yumetodo )] ( https://qiita.com/yumetodo/items/238751b879c09b56234b )
0 commit comments