itoa()
Visual Studioで実行すると警告が表示され、Linuxでプログラムをビルドしようとするとコンパイルエラーが発生するため、整数を文字列に変換する代替手段があるかどうか疑問に思っていました。
18 に答える
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/から取得
boost::lexical_castはかなりうまく機能します。
#include <boost/lexical_cast.hpp>
int main(int argc, char** argv) {
std::string foo = boost::lexical_cast<std::string>(argc);
}
考古学
itoa は、atoi 標準関数を補完するために設計された非標準のヘルパー関数であり、おそらく sprintf を隠しています (ほとんどの機能は sprintf で実装できます): http://www.cplusplus.com/reference/clibrary/cstdlib/ itoa.html
Cウェイ
sprintf を使用します。またはsnprintf。またはあなたが見つけたどんなツールでも。
彼のコメントの1つで「onebyone」が正しく言及されているように、一部の関数が標準にないという事実にもかかわらず、ほとんどのコンパイラーは代替手段を提供します(たとえば、Visual C++には独自の_snprintfがあり、必要に応じてsnprintfにtypedefできます)。
C++ の方法。
C++ ストリームを使用します (現在の場合は std::stringstream (または、Herb Sutter が著書の 1 つで提案しているように、推奨されていない std::strstream でさえ、多少高速であるため))。
結論
あなたは C++ を使用しています。つまり、好きな方法を選択できます。
より高速な方法 (つまり、C の方法) ですが、コードがアプリケーションのボトルネックであり (時期尚早の最適化は悪であるなど)、コードが安全にカプセル化されてバッファー オーバーランのリスクを回避できることを確認する必要があります。
コードのこの部分が重要ではないことがわかっている場合は、より安全な方法 (つまり、C++ の方法) です。そのため、誰かがサイズやポインターを間違えたために、コードのこの部分がランダムな瞬間に壊れないようにすることをお勧めします (これは起こります)。実生活では...昨日のように、私のコンピューターで、誰かが実際に必要とせずに高速な方法を使用するのが「クール」だと思ったからです)。
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);
舞台裏で、lexical_cast はこれを行います:
std::stringstream str;
str << myint;
std::string result;
str >> result;
このためにブーストを「ドラッグ」したくない場合は、上記を使用するのが良い解決策です。
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>
。
С++11は最終的にこの提供を解決しstd::to_string
ます。またboost::lexical_cast
、古いコンパイラーにとって便利なツールです。
私はこれらのテンプレートを使用します
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;
}
実際には、巧妙に作成された 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;
}
十分な長さの文字列を割り当ててから、snprintf を使用します。
最良の答え、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 を使用していない理由は、それらが遅すぎるためですよね?
高速で安全な整数から文字列への変換方法に興味があり、標準ライブラリに限定されない場合は、 {fmt}ライブラリのformat_int
方法をお勧めします。
fmt::format_int(42).str(); // convert to std::string
fmt::format_int(42).c_str(); // convert and get as a C string
// (mind the lifetime, same as std::string::c_str())
Boost Karma の整数から文字列への変換ベンチマークによると、このメソッドは glibc のsprintf
orよりも数倍高速ですstd::stringstream
。独立したベンチマークint_generator
によって確認されたように、Boost Karma 独自のものよりもさらに高速です。
免責事項: 私はこのライブラリの作成者です。
私はこのスレッドセーフ関数を少し前に書きましたが、結果に非常に満足しており、アルゴリズムが軽量で無駄がなく、標準の MSVC _itoa() 関数の約 3 倍のパフォーマンスを備えていると感じています。
リンクはこちらです。最適な 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です。
int number = 123;
stringstream = s;
s << number;
cout << ss.str() << endl;
すべてのstringstream
メソッドは、書式設定のためのロケール オブジェクトの使用に関するロックを伴う場合があることに注意してください。複数のスレッドからこの変換を使用している場合、これは注意が必要かもしれません...
詳しくはこちらをご覧ください。C++ で数値を指定された長さの文字列に変換する
iostream
Windows CE 派生プラットフォームでは、デフォルトで sはありません。そこに行く方法は_itoa<>
、通常、家族と一緒にいるのが好ましい_itow<>
です(とにかく、ほとんどの文字列のものはUnicodeであるため)。
上記の提案のほとんどは、技術的には C++ ではなく、C ソリューションです。
std::stringstreamの使用を調べてください。