C++で`std::string`を数値に変換するテクニック:`std::atof` 関数を超えた方法とは
- 変換に失敗した場合は、
0.0
を返します。 - 変換に成功した場合は、変換された浮動小数点数値を返します。
- 浮動小数点リテラル、指数表記、科学的記数法を含む、様々な形式の文字列を受け付けます。
- 文字列
str
を解析し、それに含まれる浮動小数点数値をdouble
型に変換します。
構文
double std::atof(const char* str);
引数
str
: 変換対象の文字列を含む C 形式の文字列ポインタ。
戻り値
- 変換に失敗した場合は、
0.0
を返します。 - 変換に成功した場合は、変換された浮動小数点数値を
double
型で返します。
例
#include <iostream>
#include <cstdlib>
int main() {
const char* str = "12.34";
double value = std::atof(str);
std::cout << "変換された値: " << value << std::endl;
return 0;
}
この例では、文字列 "12.34" を std::atof
関数に渡して、浮動小数点数値 12.34 に変換し、結果をコンソールに出力しています。
注意点
- 変換結果が
double
型の範囲を超える場合は、オーバーフローが発生し、errno
変数にERANGE
が設定されます。 - 変換対象の文字列は、有効な浮動小数点数値形式でなければなりません。そうでない場合は、変換に失敗し、
0.0
が返されます。 std::atof
は C 言語のatof
関数と互換性があり、同じ引数と戻り値を持っています。
std::string
からの変換
std::string
オブジェクトを std::atof
関数に直接渡すことはできません。std::string
オブジェクトを C 形式の文字列に変換してから、std::atof
関数に渡す必要があります。
std::string str = "56.78";
const char* c_str = str.c_str();
double value = std::atof(c_str);
この例では、std::string
オブジェクト str
の C 形式の文字列ポインタ c_str
を取得し、それを std::atof
関数に渡して、浮動小数点数値 56.78 に変換しています。
C++ 標準ライブラリには、std::atof
以外にも、文字列と数値の変換を行う様々な関数があります。
std::stod
: 文字列を倍精度浮動小数点数値に変換std::stof
: 文字列を単精度浮動小数点数値に変換std::stoull
: 文字列を符号なし長整数に変換std::stol
: 文字列を長整数に変換std::stoi
: 文字列を整数に変換
これらの関数は、それぞれ異なる型への変換に対応しており、std::atof
と同様に、std::string
オブジェクトを含む様々な種類の文字列から変換を行うことができます。
文字列から浮動小数点数値への変換
#include <iostream>
#include <cstdlib>
int main() {
const char* str1 = "12.34";
const char* str2 = "-56.78";
const char* str3 = "1.23e2";
double value1 = std::atof(str1);
double value2 = std::atof(str2);
double value3 = std::atof(str3);
std::cout << "str1 から変換された値: " << value1 << std::endl;
std::cout << "str2 から変換された値: " << value2 << std::endl;
std::cout << "str3 から変換された値: " << value3 << std::endl;
return 0;
}
出力
str1 から変換された値: 12.34
str2 から変換された値: -56.78
str3 から変換された値: 123
std::string オブジェクトからの変換
#include <iostream>
#include <cstdlib>
#include <string>
int main() {
std::string str1 = "34.56";
std::string str2 = "-78.90";
std::string str3 = "2.34e3";
const char* c_str1 = str1.c_str();
const char* c_str2 = str2.c_str();
const char* c_str3 = str3.c_str();
double value1 = std::atof(c_str1);
double value2 = std::atof(c_str2);
double value3 = std::atof(c_str3);
std::cout << "str1 から変換された値: " << value1 << std::endl;
std::cout << "str2 から変換された値: " << value2 << std::endl;
std::cout << "str3 から変換された値: " << value3 << std::endl;
return 0;
}
出力
str1 から変換された値: 34.56
str2 から変換された値: -78.9
str3 から変換された値: 2340
エラー処理
#include <iostream>
#include <cstdlib>
#include <string>
int main() {
const char* str1 = "12.34";
const char* str2 = "abc";
double value1 = std::atof(str1);
double value2 = std::atof(str2);
std::cout << "str1 から変換された値: " << value1 << std::endl;
if (std::atof(str2) == 0.0) {
std::cout << "str2 の変換に失敗しました。" << std::endl;
}
return 0;
}
出力
str1 から変換された値: 12.34
str2 の変換に失敗しました。
#include <iostream>
int main() {
double value1 = 12.34;
double value2 = -56.78;
double value3 = 1.23e2;
std::string str1 = std::to_string(value1);
std::string str2 = std::to_string(value2);
std::string str3 = std::to_string(value3);
const char* c_str1 = str1.c_str();
const char* c_str2 = str2.c_str();
const char* c_str3 = str3.c_str();
double convertedValue1 = std::atof(c_str1);
double convertedValue2 = std::atof(c_str2);
double convertedValue3 = std::atof(c_str3
std::stod 関数
std::stod
関数は、std::atof
関数と同様に、文字列を double
型の浮動小数点数値に変換するために使用されます。
構文
double std::stod(const char* str, char** endptr);
引数
endptr
: 変換が終了した文字列ポインタを格納するポインタ。str
: 変換対象の文字列を含む C 形式の文字列ポインタ。
戻り値
- 変換に失敗した場合は、
0.0
を返します。 - 変換に成功した場合は、変換された浮動小数点数値を
double
型で返します。
std::atof
との違い
std::stod
関数は、std::atof
関数よりも精度が高く、より正確な変換結果を得ることができます。std::stod
関数は、変換が終了した位置をendptr
引数に格納します。これにより、部分文字列の変換や、文字列の一部が浮動小数点数値でない場合の処理が容易になります。
例
#include <iostream>
#include <cstdlib>
int main() {
const char* str = "12.34567890123456789";
char* endptr;
double value = std::stod(str, &endptr);
std::cout << "変換された値: " << value << std::endl;
std::cout << "変換が終了した位置: " << *endptr << std::endl;
return 0;
}
出力
変換された値: 12.345678901234568
変換が終了した位置: e
std::stringstream クラス
std::stringstream
クラスは、文字列ストリームを操作するためのテンプレートクラスです。文字列ストリームを使用して、文字列を浮動小数点数値に変換することもできます。
例
#include <iostream>
#include <sstream>
int main() {
std::string str = "56.789";
double value;
std::stringstream ss(str);
ss >> value;
std::cout << "変換された値: " << value << std::endl;
return 0;
}
出力
変換された値: 56.789
手動解析
浮動小数点数値形式を解析して、手動で変換することもできます。これは、複雑な形式の浮動小数点数値を扱う場合や、より詳細な制御が必要な場合に役立ちます。
#include <iostream>
int main() {
const char* str = "123.45e-2";
double value = 0.0;
int sign = 1;
double base = 0.0;
double exponent = 0.0;
bool is_exponent = false;
bool is_fraction = false;
for (int i = 0; str[i] != '\0'; ++i) {
switch (str[i]) {
case '-':
sign *= -1;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (!is_exponent) {
base = base * 10.0 + (str[i] - '0');
} else {
exponent = exponent * 10.0 + (str[i] - '0');
}
break;
case '.':
is_fraction = true;
break;
case 'e':
case 'E':
is_exponent = true;
break;
default: