web-dev-qa-db-ja.com

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

この質問は毎週行われるため、この FAQ は多くのユーザーに役立つ可能性があります。

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

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

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

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

119
Armen Tsirunyan

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)。

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

最後に、整数型では基数を指定できます。9より大きい数字の場合、アルファベットが想定されます(a=10z=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のstringreamオプションに戻ってストリームマニピュレータを使用する必要があります。

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

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

125
KillianDS

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 を使用します。ブーストに慣れていない場合は、このlexical_castのような小さなライブラリから始めることをお勧めします。 boostとそのドキュメントをダウンロードしてインストールするには go here 。 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 *)を使用するため、その使用法mayC++の正確な実践とは言えません。 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と同じように使用されます。繰り返しますが、istringstreamistrstreamを混同しないでください。後者は非推奨です。

    #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. boost lexical cast を使用します。

    #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_castboost::bad_lexical_cast型の例外をスローします

84
Armen Tsirunyan

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);
}

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

2
JiaHao Xu

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

// 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のバージョンも必要になる場合があります。

0
Viktor Sehr