43


20

一般に、Cにバイナリデータを格納するための最良の方法は何ですか? 私が言うことができる限り、オプションはほとんど文字列かベクトルを使うことに煮詰まります。 (私は特にCを参照しているので、char *とmalloc()の可能性は省きます)。

通常は単に文字列を使用しますが、不足しているオーバーヘッド、またはSTLが内部的に行う変換によってバイナリデータの健全性が損なわれる可能性があるかどうかはわかりません。 誰かがこれに何らかのポインター(har)を持っていますか? 何らかの提案や好みはどうですか?

4 Answer


40


メモリが連続しているのでcharのベクトルはいいです。 そのため、berkleyソケットやファイルAPIなどの多くのC APIと一緒に使用できます。 たとえば、次のことができます。

std :: vector vect; ... 送信(靴下、

そしてそれはうまくいきます。

あなたは本質的に他の動的に割り当てられたcharバッファと同じように扱うことができます。 あなたは魔法の数字やパターを探して上下にスキャンすることができます。 あなたはそれを適所で部分的に解析することができます。 ソケットから受け取るためには、より多くのデータを追加するために非常に簡単にサイズを変更することができます。

欠点は、サイズ変更がそれほど効率的ではなく(サイズ変更や事前割り当てを慎重に行う)、アレイの前面からの削除も非常に効率が悪いことです。 たとえば、一度に1文字または2文字だけデータ構造の前面からポップする必要がある場合は、この処理の前に両端キューにコピーすることをお勧めします。 これにはコストがかかり、メモリのデキューは隣接していないため、C APIへのポインタを渡すことはできません。

結論として、ダイビング前にデータ構造とそのトレードオフについて学びましょう。ただし、charのベクトルは一般的に私が一般的に使用しているものです。


8


std

stringの最大の問題は、現在の規格では、その基礎となるストレージが連続していることを保証していないことです。 しかし、stringが連続していない既知のSTL実装はないため、実際にはおそらく失敗しません。 実際、新しいC 0x標準では、std :: stringがstd :: vectorなどの連続したバッファを使用するように指定することで、この問題を解決しようとしています。

文字列に対するもう1つの引数は、その名前から、バイナリバッファではなく文字列が含まれていることを示唆していることです。

とは言っても、私はベクトルもお勧めします。


6


私もこのために `std

string`を使っていますが、これまで問題はありませんでした。

昨日コードの断片の中で私が鋭いリマインダを受け取った1つの "ポインタ":バイナリデータのブロックから文字列を作成するとき、 `std

string(startIter、endIter)コンストラクタ形式を使ってくださいstd :: string(ptr、offset、length) `form - 後者は、ポインタがCスタイルの文字列を指すと仮定し、最初の0文字以降は無視します(指定された lengthまで "コピーします)。 「長さではない」


3


確かにあなたはcharの何らかのコンテナを使うべきですが、あなたが使いたいコンテナはあなたのアプリケーションに依存します。

charは、バイナリデータを保持するのに役立ついくつかのプロパティを持っています。標準はcharデータ型のための「パディング」を許可していません。これは、バイナリレイアウトでゴミが出ないことを意味するので重要です。 各charは正確に1バイトであることも保証されているため、設定された幅を持つ唯一の普通の古いデータ型(POD)になります(その他すべては上限および/または下限の観点から指定されます)。

文字を格納するための適切なstlコンテナに関する議論は、上のDougによって十分に処理されています。 どちらが必要かは、完全にあなたのユースケースによります。 特別な検索、追加/削除、またはスプライスを必要とせずに、繰り返したデータのブロックを保持しているだけの場合は、vectorを使用することをお勧めします。 NULLで終わるCスタイルの文字列を保持します。