2015-09-09 4 views
5

各文字列が固定長であるファイルの構造体から文字列を読み取っています。'\0'パディングです。格納されている文字列が長さ全体を必要とする場合、ゼロ終了しません。あまりにも、std :: stringを最大X文字から構成し、ヌル文字で停止

// char MyString[1000]; 
std::string stdmystring(MyString, ARRAYSIZE(MyString)); 

しかし、このコピーパディング:

私は現在、このような人々のうちstd::string Sを構築しています。私は今すぐ文字列をトリミングすることができますが、最初の場所でコピーを防止するエレガントで迅速な方法はありますか?

スピードはスペースより重要です。これはループで実行されるためです。

+0

POSIX strnlenを使用してサイズを判断できます。 (それ以外の場合は、何かする必要があります。それ以外の場合は、文字列:: size()は常に配列サイズです) –

+0

もちろん、最適化は間違いありません。サイズを決定するための2番目のループなしでこれを行う方法が誰もいなくなった場合は、これを使用します(これは私が考えたものです...)。 –

答えて

2

単純な溶液である:ディーターが

  • 又はstd::find(MyString,MyString+ARRAYSIZE(MyString),'\0')を示唆したように

    1. ちょうどIMEが任意遅い

    2. されていない

      • いずれかstrnlenを使用する最初の正しい長さを計算します

        あなたの文字列がキャッシュに収まる場合、それはl (スペースはそれほど重要だったと言うあなたはなかった)、そしてあなたが

      • を幅を使い果たすか(​​など)NULを打つまでの文字を追加するループを記述ikely余分なループが

      • 準備に最大文字列サイズのコスト支配実際nuls、それにstrncpyで初期化された最大サイズの文字列を作成し、そして第三は、概念的2を使用しているときに、サイズ2番目のオプションは、単一のループを使用し

    正しいようにしたい場合は、必要に応じてunused nulsを消去(それは文字列内にあるctor、次にコピー内)。しかし、各文字のpush_backは単純な文字割り当てよりも高価に見えるので、#3がもっと速い場合は驚かないでしょう。プロファイルと参照してください!まあ

  • +0

    少なくともVisual Studioでは、既知のサイズの文字列の作成にmemcpyが使用されています。これは他のどの方法よりも高速です。したがって、私はDieterの方法に行きます。 –

    2

    サイズは問題ではありません場合は、それを行うための一つの潜在的な方法は、潜在的に必要な事前に割り当てるスペースにreserve()を使用して、あなたが'\0'に遭遇するまで、それぞれの文字を追加し、空std::stringを作成することです。一つのメモリ割り当て

    std::string stdmystring; 
    stdmystring.reserve(MyString_MAX_SIZE) ; 
    for(size_t i=0;i<MyString_MAX_SIZE && MyString[i]!='\0';++i); 
    stdmystring+=MyString[i]; 
    

    reserve() garantiesあなたはMAX_SIZEを知っているので、文字列は、それよりも大きく得ることは決してないだろう。

    + =演算子関数の呼び出しはおそらくインライン展開されますが、文字列が必要な容量を持っていることを確認しなければなりません。事実、これはstrlenを使って文字列の正確な長さを最初に見つけてテストするよりも同じか悪いことがあります。

    +0

    後でいくつかの 'std :: string'実装を調べなければなりませんが、ここでは' reserve'が悲観的である可能性があると思います。小文字の最適化がOPの場合に重要であるかもしれないので、平均と文字列の長さによって異なります。 – dyp

    +0

    はい、これは当てはまりますが、状況によって異なります。短い文字列は、長い文字列のサイズ、容量、ポインタに使用されるスペースと、それぞれのサイズと短い文字列と長い文字列を区別するためのいくつかのフラグビット/ビットに合わせなければなりません。通常、短い文字列の容量は、3つの機械語よりわずかに短いです。 平均的な文字列サイズがそのreserve()に収まる場合、実際にはパフォーマンスが悪くなりますが、十分な長さの文字列がたくさんある場合、最初に予約されていない文字列は複数の割り当てとコピーによってさらに悪化する可能性があります。 – Abstraction

    0

    内部のMyString配列を1バイトで割り振り、常に最終バイトを終了し、std::stringのC文字列コンストラクタを使用するのが最も簡単な方法だと思います。 (ほとんどの場合、プロセスはI/Oがファイルにバインドされるため、C-stringコンストラクタが使用するアルゴリズムは問題ありません)。

    関連する問題