18

一時バッファを作成せずに、既知のバイト数を直接std :: stringに読み込む方法はありますか?

たとえば、現在私はそれを行うことができます

boost::uint16_t len;
is.read((char*)&len, 2);
char *tmpStr = new char[len];
is.read(tmpStr, len);
std::string str(tmpStr, len);
delete[] tmpStr;
4

6 に答える 6

11

std::string使用できるresize関数、または同じことを行うコンストラクターがあります。

boost::uint16_t len;
is.read((char*)&len, 2);

std::string str(len, '\0');
is.read(&str[0], len);

これはテストされておらず、文字列が連続したストレージを持つことが義務付けられているかどうかはわかりません。

于 2009-11-29T18:47:39.473 に答える
6

copy_nとinsert_iteratorの組み合わせを使用できます

void test_1816319()
{
    static char const* fname = "test_1816319.bin";
    std::ofstream ofs(fname, std::ios::binary);
    ofs.write("\x2\x0", 2);
    ofs.write("ab", 2);
    ofs.close();

    std::ifstream ifs(fname, std::ios::binary);
    std::string s;
    size_t n = 0;
    ifs.read((char*)&n, 2);
    std::istream_iterator<char> isi(ifs), isiend;
    std::copy_n(isi, n, std::insert_iterator<std::string>(s, s.begin()));
    ifs.close();
    _unlink(fname);

    std::cout << s << std::endl;
}

コピー、ハッキング、オーバーランの可能性、未定義の動作はありません。

于 2011-02-28T11:30:42.787 に答える
2

getline のようなものを使用できます。

#include <iostream>
#include <string>
using namespace std;

int main () {
  string str;
  getline (cin,str,' ');
}
于 2009-11-29T18:56:02.890 に答える
2

ベクトルをバッファーとして使用します。

boost::uint16_t len;
is.read((char*)&len, 2); // Note if this file was saved from a different architecture 
                         // then endianness of these two bytes may be reversed.

std::vector buffer(len);  // uninitialized.
is.read(&buffer[0], len);

std::string  str(buffer.begin(),buffer.end());

おそらく、文字列をバッファとして使用することでうまくいくでしょう(GManで説明されているように)。文字列メンバーが連続した場所にあることは標準では保証されていません (したがって、現在の実装を確認し、別のコンパイラ/プラットフォームに移植するときに確認が必要であるという大きなコメントを入れてください)。

于 2009-11-29T21:09:29.150 に答える
0

コードの長さを最適化しているだけですか、それともここにコピーを保存しようとしていますか? 一時バッファの何が問題になっていますか?

私はあなたが実際に直接書き込もうとしている文字列の保護を回避していると主張したいと思います。std::string へのコピーのパフォーマンスが心配な場合は、アプリケーションのパフォーマンスに何らかの影響を与えていることがわかっているため、char* を直接操作します。

EDIT:もっと探しています... コピーなしでchar *からstd :: stringを初期化しています

2番目の回答では、達成しようとしているものを達成できないことをかなり率直に述べています(つまり、コピーする char* を反復せずに std::string を設定します。)

ロード ルーチンを見て (おそらくここに投稿しますか?)、割り当てを最小限に抑えます。 new と delete は確かに無料ではないため、バッファを常に再作成する必要がなければ、少なくとも時間を節約できます。反復ごとに配列の最初のインデックスを終了するバッファを 0 または null に memset することで消去すると便利ですが、アルゴリズムに自信が持てたら、パフォーマンスのためにそのコードをすぐに削除できます。

于 2009-11-29T18:55:53.217 に答える
0

簡単な方法は次のとおりです。

std::istream& data
const size_t dataSize(static_cast<size_t>(data.rdbuf()->in_avail()));
std::string content;
content.reserve( dataSize);
data.read(&content[0], dataSize);
于 2013-02-01T19:38:13.607 に答える