C ++で数値を文字列に、またはその逆に変換する方法


120

この質問は毎週聞かれるので、このFAQは多くのユーザーを助けるかもしれません。

  • C ++で整数を文字列に変換する方法

  • C ++で文字列を整数に変換する方法

  • C ++で浮動小数点数を文字列に変換する方法

  • C ++で文字列を浮動小数点数に変換する方法


このような変換のために、ブックマークconverttypes.com
Firzok Nadeem

回答:


129

C ++ 11の更新

以下のようにC++11、標準的な、文字列から数の変換及びその逆の標準ライブラリにに内蔵されています。以下のすべての関数が<string>(21.5項に従って)存在します。

文字列から数値へ

float              stof(const string& str, size_t *idx = 0);
double             stod(const string& str, size_t *idx = 0);
long double        stold(const string& str, size_t *idx = 0);
int                stoi(const string& str, size_t *idx = 0, int base = 10);
long               stol(const string& str, size_t *idx = 0, int base = 10);
unsigned long      stoul(const string& str, size_t *idx = 0, int base = 10);
long long          stoll(const string& str, size_t *idx = 0, int base = 10);
unsigned long long stoull(const string& str, size_t *idx = 0, int base = 10);

これらはそれぞれ文字列を入力として受け取り、それを数値に変換しようとします。数値データがないか、数値が型の範囲外であるために、有効な数値を構築できない場合、例外がスローされます(std::invalid_argumentまたはstd::out_of_range)。

変換が成功し、そうidxでない場合0idxは、デコードに使用されなかった最初の文字のインデックスが含まれます。これは最後の文字の後ろのインデックスである可能性があります。

最後に、整数型では、ベースを指定できます。9より大きい数字の場合、アルファベットと見なされます(a=10までz=35)。ここで解析できる浮動小数点数符号付き整数、および符号なし整数の正確なフォーマットについての詳細情報を見つけることができます。

最後に、各関数には、を受け入れるオーバーロードもあります std::wstring最初のパラメーターとしてます。

数値から文字列へ

string to_string(int val);
string to_string(unsigned val);
string to_string(long val);
string to_string(unsigned long val);
string to_string(long long val);
string to_string(unsigned long long val);
string to_string(float val);
string to_string(double val);
string to_string(long double val);

これらはより簡単で、適切な数値型を渡して文字列を返します。書式設定オプションについては、C ++ 03のstringsreamオプションに戻って、ストリームマニピュレータを使用する必要があります。

コメントで述べたように、これらの関数はデフォルトの仮数精度にフォールバックしますが、これはおそらく最大精度ではありません。アプリケーションでより高い精度が必要な場合は、他の文字列フォーマット手順に戻ることも最善です。

という名前の同様の関数も定義されてto_wstringstd::wstringます。これらはを返します。


3
std::to_string浮動小数点型の精度が大幅に低下します。たとえばdouble f = 23.4323897462387526; std::string f_str = std::to_string(f);、23.432390の文字列を返します。これにより、これらの関数を使用して浮動小数点値を往復することができなくなります。
fun4jimmy 2014年

@ fun4jimmyこれは標準または実装固有の制約ですか?回答に追加します。ストリングを往復するフロートは、これまでに良い考えではありません。
KillianDS 2014年

C ++標準では「言う戻り値:各関数は呼び出すことによって生成される引数の値の文字表現保持する文字列オブジェクトを返すsprintf(buf, fmt, val)の書式指定子で『%d個』『%U』『』%ldのを」 %lu ""%lld ""%llu ""%f ""%f "、または"%Lf "、それぞれ、buf十分なサイズの内部文字バッファーを指定します。 "printfのC99標準を確認しました。 小数点以下の桁数は、#define DECIMAL_DIGfloat.h
fun4jimmy 2014年

Bruce Dawsonのブログには、浮動小数点数の往復に必要な精度に関する優れた記事がいくつかあります。
fun4jimmy 2014年

2
これらの関数はすべてグローバルロケールの影響を受けます。ライブラリを使用すると、特にスレッドを使用すると、問題が発生する可能性があります。:ここで私の質問を参照してくださいstackoverflow.com/questions/31977457/...
のIdent

86

C ++ 03で数値を文字列に変換する方法

  1. 使用しないでくださいitoaか、itof彼らは非標準のため、移植できませんので、機能を。
  2. 文字列ストリームを使用する

     #include <sstream>  //include this to use string streams
     #include <string> 
    
    int main()
    {    
        int number = 1234;
    
        std::ostringstream ostr; //output string stream
        ostr << number; //use the string stream just like cout,
        //except the stream prints not to stdout but to a string.
    
        std::string theNumberString = ostr.str(); //the str() function of the stream 
        //returns the string.
    
        //now  theNumberString is "1234"  
    }

    文字列ストリームを使用して、浮動小数点数を文字列に変換したり、希望どおりに文字列をフォーマットしたりすることもできます。 cout

    std::ostringstream ostr;
    float f = 1.2;
    int i = 3;
    ostr << f << " + " i << " = " << f + i;   
    std::string s = ostr.str();
    //now s is "1.2 + 3 = 4.2" 

    あなたは、ストリームのようなマニピュレータ、使用することができstd::endlstd::hexおよび機能をstd::setw()std::setprecision()とまったく同じように文字列ストリームとなどcout

    混同しないようにしてください std::ostringstreamstd::ostrstream。後者は非推奨です

  3. ブースト字句キャストを使用します。boostに慣れていない場合は、このlexical_castのような小さなライブラリから始めることをお勧めします。boostとそのドキュメントをダウンロードしてインストールするには、ここをクリックしてください。boostはC ++標準にはありませんが、boostの多くのライブラリーは最終的に標準化され、boostは最高のC ++ライブラリーと広く見なされています。

    字句キャストは下のストリームを使用するため、基本的にこのオプションは前のオプションと同じですが、冗長性は低くなります。

    #include <boost/lexical_cast.hpp>
    #include <string>
    
    int main()
    {
       float f = 1.2;
       int i = 42;
       std::string sf = boost::lexical_cast<std::string>(f); //sf is "1.2"
       std::string si = boost::lexical_cast<std::string>(i); //sf is "42"
    }

C ++ 03で文字列を数値に変換する方法

  1. Cから継承された最も軽量なオプションは、関数atoi(整数(アルファベットから整数))およびatof(浮動小数点値(アルファベットから浮動))です。これらの関数は、Cスタイルの文字列を引数(const char *)として取るので、その使用法、C ++の良い習慣とは言えません。cplusplus.comには、atoiatofの両方に関する理解しやすいドキュメントがあり、入力が正しくない場合の動作を含めています。ただし、リンクにエラーが含まれているため、標準に従って、入力数が大きすぎてターゲットタイプに収まらない場合、動作は未定義です。

    #include <cstdlib> //the standard C library header
    #include <string>
    int main()
    {
        std::string si = "12";
        std::string sf = "1.2";
        int i = atoi(si.c_str()); //the c_str() function "converts" 
        double f = atof(sf.c_str()); //std::string to const char*
    }
  2. 文字列ストリームを使用します(今回は入力文字列ストリーム、istringstream)。繰り返しになりますが、istringstreamはと同じように使用されcinます。繰り返しますが、と混同istringstreamしないでくださいistrstream。後者は非推奨です。

    #include <sstream>
    #include <string>
    int main()
    {
       std::string inputString = "1234 12.3 44";
       std::istringstream istr(inputString);
       int i1, i2;
       float f;
       istr >> i1 >> f >> i2;
       //i1 is 1234, f is 12.3, i2 is 44  
    }
  3. ブースト字句キャストを使用します。

    #include <boost/lexical_cast.hpp>
    #include <string>
    
    int main()
    {
       std::string sf = "42.2"; 
       std::string si = "42";
       float f = boost::lexical_cast<float>(sf); //f is 42.2
       int i = boost::lexical_cast<int>(si);  //i is 42
    }       

    不正な入力の場合、lexical_castタイプの例外をスローしますboost::bad_lexical_cast


4
のcplusplusのドキュメントatoiは優れていません。正しくありません。文字列の数値がで表現できない場合int、動作は未定義であることは述べられていません。代わりに、範囲外の値はINT_MAX/ INT_MINに固定されていると言っています。これは、C ++ 03でもC89でも見つかりません。信頼できない/未検証の入力の場合、またはストリームがサポートしていないベースを処理する場合はstrtol、エラー動作が定義されているが必要です。atof/ に対する同様のコメントstrtod
Steve Jessop、2011年

2
cplusplus.comは "atoi"について間違っています。戻り値について「有効な変換を実行できなかった場合はゼロ値が返されます。正しい値が表現可能な値の範囲外の場合は、INT_MAXまたはINT_MINが返されます。」とありますが、仕様では「結果の値を表すことができません。動作は未定義です。」そして、「エラー時の動作を除いて、それらはと同等(int)strtol(nptr, (char **)NULL, 10)です。atoi[...]関数は、変換された値を返します。」cplusplus.comは、初心者にとって信じられないほど悪い情報源であることが知られています。
ヨハネスシャウブ-litb

istr >> i1 >> f >> i2;成功のチェックに失敗しました。
sbi

4
追加する可能性がありますstd::to_string
Pubby

1
@ArmenTsirunyan:私の終わりから+10、私がこれまで深く見た中で最高の答えの1つ。ご回答有難うございます。
Abhineet、2012年

4

C ++ 17では、新しい関数std :: to_charsおよびstd :: from_charsがヘッダーcharconvに導入されています。

std :: to_charsは、ロケールに依存せず、割り当てもスローもされません。

他のライブラリ(std :: sprintfなど)で使用されるフォーマットポリシーの小さなサブセットのみが提供されます。

以下からのstd :: to_charsのために同じ、のstd :: from_chars

std :: from_charsがto_charsでフォーマットされたすべての浮動小数点値を正確に回復できるという保証は、両方の関数が同じ実装のものである場合にのみ提供されます

 // See en.cppreference.com for more information, including format control.
#include <cstdio>
#include <cstddef>
#include <cstdlib>
#include <cassert>
#include <charconv>

using Type =  /* Any fundamental type */ ;
std::size_t buffer_size = /* ... */ ;

[[noreturn]] void report_and_exit(int ret, const char *output) noexcept 
{
    std::printf("%s\n", output);
    std::exit(ret);
}
void check(const std::errc &ec) noexcept
{
    if (ec ==  std::errc::value_too_large)
        report_and_exit(1, "Failed");
}
int main() {
    char buffer[buffer_size];        
    Type val_to_be_converted, result_of_converted_back;

    auto result1 = std::to_chars(buffer, buffer + buffer_size,  val_to_be_converted);
    check(result1.ec);
    *result1.ptr = '\0';

    auto result2 = std::from_chars(buffer, result1.ptr, result_of_converted_back);
    check(result2.ec);

    assert(val_to_be_converted == result_of_converted_back);
    report_and_exit(0, buffer);
}

コンパイラによって完全に実装されているわけではありませんが、間違いなく実装されます。


0

この便利なクラスをStackOverflowのどこかから盗んで、ストリーミング可能なものを文字列に変換しました。

// make_string
class make_string {
public:
  template <typename T>
  make_string& operator<<( T const & val ) {
    buffer_ << val;
    return *this;
  }
  operator std::string() const {
    return buffer_.str();
  }
private:
  std::ostringstream buffer_;
};

そして、それを次のように使用します。

string str = make_string() << 6 << 8 << "hello";

かなり気の利いた!

また、この関数を使用して、文字列をストリーミング可能なものに変換しますが、数値を含まない文字列を解析しようとすると、安全ではありません。 (そして最後のものほど賢くない)

// parse_string
template <typename RETURN_TYPE, typename STRING_TYPE>
RETURN_TYPE parse_string(const STRING_TYPE& str) {
  std::stringstream buf;
  buf << str;
  RETURN_TYPE val;
  buf >> val;
  return val;
}

使用:

int x = parse_string<int>("78");

wstringのバージョンも必要になる場合があります。


5
これはまさにboost :: lexical_castが行うことです。そして、ブーストは、より一般的な方法でそれを行います。
Armen Tsirunyan

確かに、私は最初の答えをざっと読みましたが、boost :: lexical_castsを見ませんでした。
Viktor Sehr 2011年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.