web-dev-qa-db-ja.com

memcpy()関数を使用して、unsignedchar配列からstd :: stringにバイトを配置します

Std :: string変数があります。そして、unsignedcharsの配列からいくつかのバイトをそれに入れる必要があります。私は最初のバイトとレッグスを知っています。

Std :: string :: assign関数を使用できます。私はそれをしました。

しかし、私はmemcpy関数を使用してその問題を正しい方法で解決したいと思います。

std::string newString;
memcpy(&newString, &bytes[startIndex], length);

私はそれが間違っていることを知っています。 std :: vectorを使用して調査し、いくつかのアイデアを見つけました。

この問題の最もエレガントな解決策を見つけるのを手伝ってください。

12

文字列を作成しているだけなので、2つのイテレータを使用する _std::string_ コンストラクタがあります。

_template< class InputIt >
basic_string( InputIt first, InputIt last, 
              const Allocator& alloc = Allocator() );
_

私たちが提供できるもの:

_std::string newString(&bytes[startIndex], &bytes[startIndex] + length);
_

文字列を作成せず、代わりに既存の文字列に割り当てる場合でも、assign()を使用することをお勧めします。それがまさにその関数の目的です。

_oldString.assign(&bytes[startIndex], &bytes[startIndex] + length);
_

しかし、何らかの理由で本当にmemcpy()を主張する場合は、文字列に実際にコピーするのに十分なデータがあることを確認する必要があります。そして、宛先アドレスとして_&str[0]_を使用してコピーします

_oldString.resize(length); // make sure we have enough space!
memcpy(&oldString[0], &bytes[startIndex], length);
_

C++ 11より前では、文字列がメモリに連続して格納されるという保証は技術的にはありませんが、実際にはこれはとにかく行われていました。

19
Barry

データを受信するための適切なサイズのバッファーが存在するように文字列のサイズを設定し、data()から取得したポインターから定数をキャストする必要があります。

std::string newString;
newString.resize(length);
memcpy((char*)newString.data(), &bytes[startIndex], length);

もちろん、これはすべて未定義の振る舞いの領域にありますが、それでもかなり標準的です。

0
shoosh