53

長さが異なるいくつかの数字 (1、999、76492 など) があり、それらすべてを共通の長さの文字列に変換したい (たとえば、長さが 6 の場合、それらの文字列は「000001」になります) 、「000999」、「076492」)。

つまり、正しい量の先頭のゼロを数値に追加する必要があります。

int n = 999;
string str = some_function(n,6);
//str = '000999'

C++でこのような関数はありますか?

4

8 に答える 8

75

またはstringstreamsを使用します。

#include <sstream>
#include <iomanip>

std::stringstream ss;
ss << std::setw(10) << std::setfill('0') << i;
std::string s = ss.str();

iostreamのタイプセーフな方法がもっと好きなので、 arachnoid.comで見つけた情報をまとめました。さらに、このコードは他の出力ストリームでも同様に使用できます。

于 2008-10-22T11:49:35.423 に答える
17
char str[7];
snprintf (str, 7, "%06d", n);

snprintfを参照

于 2008-10-22T11:36:58.337 に答える
10

知っておくべきことの1 つは、このstringstreamアプローチを使用するときにロックが発生する可能性があることです。少なくとも、Visual Studio 2008 に同梱されている STL では、フォーマット中にさまざまなロケール情報が使用されるため、多くのロックが解除および解放されます。これは、数値を文字列に同時に変換している可能性のあるスレッドの数に応じて、問題になる場合とそうでない場合があります...

このsprintfバージョンはロックを必要としないため (少なくとも、現在開発中のロック監視ツールによると...)、並行状況での使用には「より良い」可能性があります。

私がこれに気付いたのは、私のツールが最近、私のサーバー システムで最も競合しているロックの 1 つとして「ロケール」ロックを吐き出したからです。それはちょっとした驚きであり、私が取ってきたアプローチを修正する可能性があります(つまりsprintf、からに戻るstringstream)...

于 2008-10-22T17:08:08.137 に答える
4

このメソッドはストリームも sprintf も使用しません。ロックの問題以外に、ストリームはパフォーマンスのオーバーヘッドを引き起こし、実際にはやり過ぎです。ストリームの場合、オーバーヘッドは、ストリームとストリーム バッファーを作成する必要があるためです。sprintf の場合、フォーマット文字列を解釈する必要があるため、オーバーヘッドが生じます。これは、nが負の場合や、nの文字列表現がlenより長い場合でも機能します。これが最速のソリューションです。

inline string some_function(int n, int len)
{
    string result(len--, '0');
    for (int val=(n<0)?-n:n; len>=0&&val!=0; --len,val/=10)
       result[len]='0'+val%10;
    if (len>=0&&n<0) result[0]='-';
    return result;
}
于 2008-10-22T12:25:18.830 に答える
4

これには多くの方法があります。最も簡単なのは次のとおりです。

int n = 999;
char buffer[256]; sprintf(buffer, "%06d", n);
string str(buffer);
于 2008-10-22T11:33:38.967 に答える
3

stringstreamは(xtoflが指摘したように)実行します。Boost形式は、snprintfのより便利な代替手段です。

于 2008-10-22T11:55:35.367 に答える
1

sprintf は、これを行う C に似た方法であり、C++ でも機能します。

C++ では、文字列ストリームとストリーム出力フォーマット ( http://www.arachnoid.com/cpptutor/student3.htmlを参照) の組み合わせが機能します。

于 2008-10-22T11:33:58.997 に答える