私のコメントはどんどん長くなっているので、ここに完全な答えがあります:
バッファchar *
は、文字列の長さを最初のXバイトに格納する必要があります(Pascalのように)。その長さの後に文字列データがあり、好きな文字を含めることができます。その後、次のXバイトで次の文字列の長さがわかります。以下同様に、空の文字列で区切られる最後まで続きます(つまり、最後のXバイトは次の文字列の長さがゼロであると主張し、アプリケーションはこれを信号としてそれ以上の文字列の検索を停止します)。
1つの利点は、文字列データをスキャンする必要がないことです。最初の文字列の先頭から次の文字列を見つけるにはO(1)時間がかかり、リストにある文字列の数を見つけるにはO(n)時間がかかります。それでも非常に高速です(O(n)が受け入れられない場合は、これを回避できますが、今すぐ始める価値はないと思います)。
もう1つの利点は、文字列データに任意の文字を含めることができることです。これは欠点である可能性があります-文字列にNUL文字が含まれている可能性がある場合は、安全に抽出できますが、C文字列関数(strlen()
またはstrcat()
)に渡さないように注意する必要があります。これにより、NUL文字が末尾として表示されます。あなたのデータの(それはそうであるかもしれないし、そうでないかもしれない)。memcpy()
ポインタ演算に依存する必要があります。
問題は、Xの値(文字列の長さを格納するために使用するバイト数)です。最も簡単なのは1で、これはすべてのエンディアンと配置の問題をバイパスしますが、文字列を255文字に制限します。これがあなたが生きることができる制限であるならば、素晴らしいです、しかし255は私には少し低いようです。
Xは2バイトまたは4バイトである可能性がありますが、少なくともそのバイト数(stdint.h
'suint16_t
またはuint32_t
、または多分uint_least16_t
またはuint_least32_t
)である(符号なし)データ型があることを確認する必要があります。タイプは、格納したい任意の文字列の長さを格納できることが保証されているためX = sizeof(size_t)
、より良い解決策はを作成することです。size_t
アラインメントをX > 1
導入し、ネットワークの移植性が問題になる場合はエンディアンを導入します。size_t
最初のXバイトを変数として読み取る最も簡単な方法は、char *
データをaにキャストしsize_t *
、単に逆参照することです。char *
ただし、データが適切に配置されていることを保証できない限り、一部のシステムではこれが機能しなくなります。データの整列を保証している場合でもchar *
、次の文字列の長さの値が整列されていることを確認するために、ほとんどの文字列の最後で数バイトを浪費する必要があります。
sizeof(size_t)
アラインメントを克服する最も簡単な方法は、最初のバイトを手動でsize_t
値に変換することです。データをリトルエンディアンとビッグエンディアンのどちらで保存するかを決定する必要があります。ほとんどのコンピューターはネイティブでリトルエンディアンですが、手動変換の場合、これは重要ではありません。1つだけ選択してください。ビッグエンディアンの4バイトに格納された数値65537(2 ^ 16 + 2)は、次のようになり{ 0, 1, 0, 2 }
ます。リトルエンディアン、{ 2, 0, 1, 0 }
。
決定したら(どちらでも構いません)、データの最初のXポイントをunsigned char
sにキャストし、次ににキャストsize_t
し、適切な指数でビットシフトしてそれらを適切な場所に配置し、それらをすべて一緒に追加します。上記の例では、0に2 ^ 32、1 x 2 ^ 16、0 x 2 ^ 8、2 x 2 ^ 0(または1)を掛けて、0 + 65536 + 0+2または65537を生成します。手動変換を行う場合、ビッグエンディアンとリトルエンディアンの効率の差はゼロになります-私が知る限り、選択は完全に任意であることを(もう一度)指摘したいと思います。
手動変換を行うと、アライメントの問題が回避され、システム間のエンディアンに関する懸念が完全に回避されるため、リトルエンディアンのコンピューターからビッグエンディアンのコンピューターに転送されるデータも同じように読み取られます。sizeof(size_t) == 4
システムからどこにデータが転送されるかについては、まだ潜在的な問題がありsizeof(size_t) == 8
ます。これが問題になる場合は、a)捨てsize_t
て不変のサイズを選択するか、b)次の値をエンコード(1バイトで十分です)することができます。sizeof(size_t)
データの最初のバイトとして送信者に対して、受信者に必要な調整を行わせる。選択a)は簡単かもしれませんが、問題が発生する可能性があります(ネットワーク上のレガシーコンピューターを考慮するには小さすぎるサイズを選択し、段階的に廃止されると、データを保存するためのスペースが不足し始めます)。実行しているシステム(16ビット、32ビット、64ビット、将来的には128ビットでも)に合わせて拡張できるため、b)を選択することをお勧めしますが、そのような作業は必要ない場合があります。 。
</vomit>
私が書いたばかりの混乱をすべて整理するのは読者に任せます。