web-dev-qa-db-ja.com

整数を文字列C ++に変換するためのitoa()の代替?

Visual Studioで実行すると警告が表示され、Linuxでプログラムをビルドしようとするとコンパイルエラーが発生するため、整数を文字列に変換するitoa()に代わるものがあるかどうか疑問に思いました。

138
Tomek

C++ 11では、 std::to_string を使用できます。

#include <string>

std::string s = std::to_string(5);

C++ 11より前のバージョンで作業している場合は、C++ストリームを使用できます。

#include <sstream>

int i = 5;
std::string s;
std::stringstream out;
out << i;
s = out.str();

http://notfaq.wordpress.com/2006/08/30/c-convert-int-to-string/ から取得

171
spoulson

boost :: lexical_cast は非常にうまく機能します。

#include <boost/lexical_cast.hpp>
int main(int argc, char** argv) {
    std::string foo = boost::lexical_cast<std::string>(argc);
}
54
Leon Timmermans

考古学

itoaは、atoi標準関数を補完するように設計された非標準のヘルパー関数であり、おそらくsprintfを隠しています(その機能のほとんどはsprintfの観点から実装できます): http://www.cplusplus.com/reference/ clibrary/cstdlib/itoa.html

Cウェイ

Sprintfを使用します。またはsnprintf。またはあなたが見つけるどんなツールでも。

「onebyone」が彼のコメントの1つで正しく言及しているように、一部の関数は標準に含まれていませんが、ほとんどのコンパイラは代替手段を提供します(たとえば、Visual C++には独自の_snprintfがあり、必要に応じてtypeprintにtypedefできます)。

C++の方法。

C++ストリームを使用します(現在のケースではstd :: stringstream(または、非推奨のstd :: strstreamでも、Herb Sutterの著書の1つで提案されているように、やや高速です)。

結論

C++を使用しているため、希望する方法を選択できます。

  • より高速な方法(つまり、Cの方法)ですが、コードがアプリケーションのボトルネックであること(時期尚早な最適化は悪意があるなど)と、バッファーオーバーランのリスクを回避するためにコードが安全にカプセル化されていることを確認する必要があります。

  • より安全な方法(つまり、C++の方法)、コードのこの部分は重要ではないことがわかっているので、誰かがサイズやポインターを間違えたためにコードのこの部分がランダムな瞬間に壊れないことを確認してください昨日、私のコンピューターで、誰かが本当に必要とせずに高速な方法を使用することが「クール」だと思ったためです。

47
paercebal

Sprintf()を試してください:

char str[12];
int num = 3;
sprintf(str, "%d", num); // str now contains "3"

sprintf()はprintf()に似ていますが、文字列に出力します。

また、コメントでParappaが言及したように、snprintf()を使用して、バッファオーバーフローの発生を停止したい場合があります(変換する数値が文字列のサイズに適合しない場合)。

snprintf(str, sizeof(str), "%d", num);
34
Jeremy Ruten

舞台裏では、lexical_castはこれを行います:

std::stringstream str;
str << myint;
std::string result;
str >> result;

このためにブーストを「ドラッグイン」したくない場合は、上記を使用するのが良い解決策です。

20

C++で独自のiota関数を次のように定義できます。

string itoa(int a)
{
    string ss="";   //create empty string
    while(a)
    {
        int x=a%10;
        a/=10;
        char i='0';
        i=i+x;
        ss=i+ss;      //append new character at the front of the string!
    }
    return ss;
}

#include <string>を忘れないでください。

10
Tag318

С++ 11は、最終的にこれを解決して std::to_string を提供します。また、boost::lexical_castは古いコンパイラ用の便利なツールです。

9
Vasaka

これらのテンプレートを使用します

template <typename T> string toStr(T tmp)
{
    ostringstream out;
    out << tmp;
    return out.str();
}


template <typename T> T strTo(string tmp)
{
    T output;
    istringstream in(tmp);
    in >> output;
    return output;
}
8
jm1234567890

Boost.Format または FastFormat を試してください。両方の高品質C++ライブラリ:

int i = 10;
std::string result;

Boost.Formatで

result = str(boost::format("%1%", i));

またはFastFormat

fastformat::fmt(result, "{0}", i);
fastformat::write(result, i);

明らかに、どちらも単一の整数の単純な変換よりもはるかに多くのことを行います

6
dcw

実際には、巧妙に作成された1つのテンプレート関数を使用して、何でも文字列に変換できます。このコード例では、ループを使用してWin-32システムにサブディレクトリを作成します。文字列連結演算子operator +は、ルートとサフィックスを連結してディレクトリ名を生成するために使用されます。接尾辞は、ループ制御変数iをC++文字列に変換し、テンプレート関数を使用して、別の文字列と連結することにより作成されます。

//Mark Renslow, Globe University, Minnesota School of Business, Utah Career College
//C++ instructor and Network Dean of Information Technology

#include <cstdlib>
#include <iostream>
#include <string>
#include <sstream> // string stream
#include <direct.h>

using namespace std;

string intToString(int x)
{
/**************************************/
/* This function is similar to itoa() */
/* "integer to alpha", a non-standard */
/* C language function. It takes an   */
/* integer as input and as output,    */
/* returns a C++ string.              */
/* itoa()  returned a C-string (null- */
/* terminated)                        */
/* This function is not needed because*/
/* the following template function    */
/* does it all                        */
/**************************************/   
       string r;
       stringstream s;

       s << x;
       r = s.str();

       return r;

}

template <class T>
string toString( T argument)
{
/**************************************/
/* This template shows the power of   */
/* C++ templates. This function will  */
/* convert anything to a string!      */
/* Precondition:                      */
/* operator<< is defined for type T    */
/**************************************/
       string r;
       stringstream s;

       s << argument;
       r = s.str();

       return r;

}

int main( )
{
    string s;

    cout << "What directory would you like me to make?";

    cin >> s;

    try
    {
      mkdir(s.c_str());
    }
    catch (exception& e) 
    {
      cerr << e.what( ) << endl;
    }

    chdir(s.c_str());

    //Using a loop and string concatenation to make several sub-directories
    for(int i = 0; i < 10; i++)
    {
        s = "Dir_";
        s = s + toString(i);
        mkdir(s.c_str());
    }
    system("PAUSE");
    return EXIT_SUCCESS;
}
6
Mark Renslow

十分な長さの文字列を割り当ててから、snprintfを使用します。

3
Iain

IMOという最良の答えは、次の機能です。

http://www.jb.man.ac.uk/~slowe/cpp/itoa.html

多くのライブラリで提供される非ANSI関数を模倣しています。

char* itoa(int value, char* result, int base);

また、超高速で、-O3の下で最適化されます。c++ string_format()...またはsprintfを使用していない理由は、それらが遅すぎるからですよね?

2
Erik Aronesty

私はこのthread-safe関数を書きましたが、結果に非常に満足しており、アルゴリズムが軽量で無駄がなく、パフォーマンスが約3X標準MSVC _itoa()関数。

こちらがリンクです。 最適なBase-10のみitoa()関数? パフォーマンスは、sprintf()の少なくとも10倍です。ベンチマークは、次のように関数のQAテストでもあります。

start = clock();
for (int i = LONG_MIN; i < LONG_MAX; i++) {
    if (i != atoi(_i32toa(buff, (int32_t)i))) {
        printf("\nError for %i", i);
    }
    if (!i) printf("\nAt zero");
}
printf("\nElapsed time was %f milliseconds", (double)clock() - (double)(start));

呼び出し元のアドレス空間のバッファ内のどこかに結果が浮いたままになる、呼び出し元のストレージの使用についていくつかの愚かな提案があります。それらを無視します。ベンチマーク/ QAコードが示すように、リストしたコードは完全に機能します。

このコードは組み込み環境で使用するのに十分な無駄がないと思います。もちろん、YMMV。

1
user1899861
int number = 123;

stringstream = s;

s << number;

cout << ss.str() << endl;
1
Kendra

すべてのstringstreamメソッドmayには、フォーマットのためのロケールオブジェクトの使用のロックが含まれることに注意してください。複数のスレッドからこの変換を使用している場合は、このに注意する必要があります...

詳細はこちらをご覧ください。 C++で指定された長さの文字列に数値を変換する

1
Len Holgate

高速で安全な整数から文字列への変換方法に興味があり、標準ライブラリに限定されない場合は、 C++ Format ライブラリのFormatIntメソッドをお勧めします。

fmt::FormatInt(42).str();   // convert to std::string
fmt::FormatInt(42).c_str(); // convert and get as a C string
                            // (mind the lifetime, same as std::string::c_str())

Boost Karmaの 整数から文字列への変換ベンチマーク によると、この方法はglibcのsprintfまたはstd::stringstreamよりも数倍高速です。 独立したベンチマーク で確認されたように、Boost Karmaのint_generatorよりもさらに高速です。

免責事項:私はこのライブラリの著者です。

1
vitaut

Windows CE派生プラットフォームでは、デフォルトでiostreamsはありません。そこに行く方法は、_itoa<>ファミリー、通常は_itow<>を使用することです(ほとんどの文字列はUnicodeであるため)。

0
Johann Gerell