C++編 逆引き 文字列を整数に変換する

先頭へ戻る

目的

"100" や "-50" のような文字列を、整数型の値に変換したいとします。 前者なら 100、後者なら -50 にします。

"100abc" のように、整数と関係の無い文字が登場した場合、その手前までで打ち切ります。 また、"abc100" の場合は、先頭部分が整数と関係の無い文字なので、変換に失敗します。

方法①(std::stoi関数を使う)[C++11~]

C++11以降であれば、std::stoi関数があります。 この関数は、C言語の strtol関数をラップしたもので、 変換のエラーを、例外によって報告するようになっています。

#include <iostream>
#include <string>

int main()
{
	try {
		int v;

		v = std::stoi("100");
		std::cout << v << std::endl;

		v = std::stoi("-50");
		std::cout << v << std::endl;

		v = std::stoi("+50");
		std::cout << v << std::endl;

		v = std::stoi("0");
		std::cout << v << std::endl;

		v = std::stoi("100abc");
		std::cout << v << std::endl;

		v = std::stoi("abc100");  // 失敗する
		std::cout << v << std::endl;
	}
	catch (const std::invalid_argument& ex) {
		std::cerr << ex.what() << std::endl;
	}
	catch (const std::out_of_range& ex) {
		std::cerr << ex.what() << std::endl;
	}
}

実行結果:

100
-50
50
0
100
invalid stoi argument

先頭の文字が数字でない場合のように、変換がまったく行われなかった場合は、 std::invalid_argument例外が、 変換結果が大きすぎたり、小さすぎたりして、表現できない場合は、 std::out_of_range例外が送出されます。

また、strtol関数のように、 変換できなかった最初の文字を得るための第2引数 (strtol関数はポインタを使いますが、std::stoi関数は std::size_t型を使い文字数で表現されます)や、 基数を指定する第3引数があります。 これらの引数には、デフォルト値が設定されているため、上記サンプルプログラムのように、 省略してしまっても動作します。

方法②(std::istringstream を使う)[C++03~]

C++11 の機能が使えない場合は、 std::istringstream を使います。

#include <iostream>
#include <sstream>

int main()
{
	int v;

	std::istringstream iss1("100");
	iss1 >> v;
	if (iss1) {
		std::cout << v << std::endl;
	}

	std::istringstream iss2("-50");
	iss2 >> v;
	if (iss2) {
		std::cout << v << std::endl;
	}

	std::istringstream iss3("+50");
	iss3 >> v;
	if (iss3) {
		std::cout << v << std::endl;
	}

	std::istringstream iss4("0");
	iss4 >> v;
	if (iss4) {
		std::cout << v << std::endl;
	}

	std::istringstream iss5("100abc");
	iss5 >> v;
	if (iss5) {
		std::cout << v << std::endl;
	}

	std::istringstream iss6("abc100");
	iss6 >> v;
	if (iss6) {
		std::cout << v << std::endl;
	}
}

実行結果:

100
-50
50
0
100

>>演算子によって読み取りを行う際にエラーが起きた場合、 ストリームの状態(【標準ライブラリ】第27章)が変化しています。 「if (iss1)」のような判定によって、ストリームの状態が正常かどうか分かるので、 これを使って、エラーが発生していないかどうかチェックしています。


参考リンク

更新履歴

'2017/6/13 新規作成。





逆引きのトップページへ

C++編のトップページへ

Programming Place Plus のトップページへ


このエントリーをはてなブックマークに追加
rss1.0 取得ボタン RSS