Skip to content

new page strtol.md #1475

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jul 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion reference/charconv.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ XMLやJSONに代表されるテキストベースのデータを利用するケ
| `snprintf` | ロケール依存、フォーマットの動的解析 |
| `sscanf` | ロケール依存、フォーマットの動的解析 |
| [`atol`](/reference/cstdlib/atoi_atol_atoll.md) | ロケール依存、エラー報告の不足 |
| `strtol` | ロケール依存、先頭ホワイトスペースの無視、接頭辞(0x等)を考慮する |
| [`strtol`](/reference/cstdlib/strtol.md) | ロケール依存、先頭ホワイトスペースの無視、接頭辞(0x等)を考慮する |
| `strstream` | ロケール依存、先頭ホワイトスペースの無視 |
| `stringstream` | ロケール依存、先頭ホワイトスペースの無視、動的メモリ確保 |
| `num_put / num_get facets` | ロケール依存、仮想関数 |
Expand Down
2 changes: 1 addition & 1 deletion reference/cstdlib.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
| [`atol`](cstdlib/atoi_atol_atoll.md) | 文字列を`long`型に変換する (function) | |
| [`atoll`](cstdlib/atoi_atol_atoll.md) | 文字列を`long long`型に変換する (function) | C++11 |
| [`atof`](cstdlib/atof.md) | 文字列を`double`型に変換する (function) | |
| `strtol` | 文字列を、基数を指定して`long`型に変換する (function) | |
| [`strtol`](cstdlib/strtol.md) | 文字列を、基数を指定して`long`型に変換する (function) | |
| `strtoll` | 文字列を、基数を指定して`long long`型に変換する (function) | C++11 |
| `strtoul` | 文字列を、基数を指定して`unsigned long`型に変換する (function) | |
| `strtoull` | 文字列を、基数を指定して`unsigned long long`型に変換する (function) | C++11 |
Expand Down
92 changes: 92 additions & 0 deletions reference/cstdlib/strtol.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# strtol
* cstdlib[meta header]
* std[meta namespace]
* function[meta id-type]

```cpp
namespace std {
long int strtol(const char* nptr, char** endptr, int base);
}
```

## 概要
文字列`nptr`を`long`型の整数に変換する。文字列は`base`で指定された基数に従って解釈される。

`endptr`が非`nullptr`の場合、変換が終了した位置の文字へのポインタがそこに格納される。

基数`base`は 2~36 または 0 の値を取る。

`base`が0の場合
- 文字列の先頭が`0x`または`0X`のときは16進数
- 文字列の先頭が`0`のときは8進数
- その他のときは10進数として変換する。

変換は次のように行われる
- 先頭が空白文字の場合、最初の非空白文字から変換される。
- `+`または`-`が先頭にある場合は、符号として解釈される。
- 基数が 16 または 0 の場合`0x`または`0X`をスキップする
- その後の文字列を、指定された`base`に基づいて整数値に変換する。
- 各桁は、`0`〜`9`をその値、`a`〜`z`および`A`〜`Z`を10〜35として扱う。

## 戻り値
- 変換可能ならば変換後の数値。
- 変換後の数値が`long`の範囲外の場合、`LONG_MAX`または `LONG_MIN`。
- 変換不可能なら`0`を返す。

## 備考
- 数値が `long` の範囲を超えるときは `errno` に `ERANGE` が設定される。

## 例
```cpp example
#include <iostream>
#include <cstdlib>
#include <cerrno>
#include <climits>

void convert_and_print(const char* str, int base) {
errno = 0;
char* end = nullptr;
long result = std::strtol(str, &end, base);

std::cout << "基数" << base << "での変換結果: " << result << std::endl;
if (str == end) {
std::cout << "変換不可" << std::endl;
} else if (errno == ERANGE) {
std::cout << " → 変換結果が範囲外" << std::endl;
}
if (*end != '\0') {
std::cout << "未変換部分: \"" << end << "\"" << std::endl;
}
std::cout << std::endl;
}

int main() {
const char* str = " -0x2Fabc";
convert_and_print(str, 0); // 自動判別
convert_and_print(str, 10); // 10進数
convert_and_print(str, 36); // 36進数

return 0;
}

```
### 出力
```
基数0での変換結果: -195260

基数10での変換結果: 0
未変換部分: "x2Fabc"

基数36での変換結果: -1999456248

```

## 関連項目
- [`strtoll`](strtoll.md.nolink): 文字列を、基数を指定して`long long`型に変換する
- [`strtoul`](strtoul.md.nolink): 文字列を、基数を指定して`unsigned long`型に変換する
- [`strtoull`](strtoull.md.nolink): 文字列を、基数を指定して`unsigned long long`型に変換する
Comment on lines +85 to +87
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- [`strtoll`](strtoll.md.nolink): 文字列を、基数を指定して`long long`型に変換する
- [`strtoul`](strtoul.md.nolink): 文字列を、基数を指定して`unsigned long`型に変換する
- [`strtoull`](strtoull.md.nolink): 文字列を、基数を指定して`unsigned long long`型に変換する
- [`strtoll`](strtoll.md.nolink): 基数を指定して文字列を`long long`型に変換する
- [`strtoul`](strtoul.md.nolink): 基数を指定して文字列を`unsigned long`型に変換する
- [`strtoull`](strtoull.md.nolink): 基数を指定して文字列を`unsigned long long`型に変換する

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

関連項目の部分の記述は、csdlib.mdにかかれているものを持ってきたのですが、合わせたほうがいいのかなと

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cstdlib の方の説明でそうなっているのには気づいていませんでした。

特に合わせなければならないということもないように思います。現に、既存のページの関連項目で、そのページの関数とリンク先のページの関数の「関係性・違い」を中心にした説明にしている場合も多くあるように思います。例えばシンプルに "long 型版" みたいな感じで。

cstdlib の説明の方を見ると「文字列を~」というのが並んでいるので、その並び方との一貫性で「文字列を」から始めているのは理解できるような気がします。一方で、今回の文脈では、「文字列を、基数を指定してunsigned long型に変換する」というのは日本語として間違いではないですが、ぎこちないというか余り普通じゃない気がするのですが、私の主観でしょうか。まあ、単に表現の仕方の話なので、最終的な判断はお任せします。

- [`std::stol`](/reference/string/stol.md): 文字列から`long`型への変換
- [`<charconv>` ヘッダ](/reference/charconv.md): 高速な文字列 ⇔ 数値変換

## 参考文献
- Qiita: [Cのstrtolの使い方とendptrの活用例(@yumetodo)](https://qiita.com/yumetodo/items/238751b879c09b56234b)
2 changes: 1 addition & 1 deletion reference/string/stoi.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ int stoi(const std::wstring& str, std::size_t* idx = nullptr, int base = 10) {
## 関連リンク
### C標準ライブラリに由来する関数
- [`atoi`](/reference/cstdlib/atoi_atol_atoll.md): `stoi`は[`atoi`](/reference/cstdlib/atoi_atol_atoll.md)を`std::string`および`std::wstring`に対応させたものと見なせる。
- `strtol`, `wcstol`: `stoi`は`strtol`および`wcstol`をそれぞれ`std::string`と`std::wstring`に対応させ、戻り値の型を`int`に変更したものと見なせる。
- [`strtol`](/reference/cstdlib/strtol.md), `wcstol`: `stoi`は`strtol`および`wcstol`をそれぞれ`std::string`と`std::wstring`に対応させ、戻り値の型を`int`に変更したものと見なせる。

### ファミリー
- (`stoi`: この関数自身)
Expand Down