警告:次のコードは、現在のプラットフォームのエンディアンを使用してデータをいじっています。同じエンディアンやその他の関連するアーキテクチャ パラメータを持たない可能性のある他のプラットフォームにこれを送信する場合は注意してください。
floatの文字列表現ではなく、float の 4 バイトを文字列の memory に配置していることを理解していると仮定します。たとえば、値 2 の整数の場合、char 値 '\0'、'\0'、'\0'、'\2' を文字列に入れます。これは、'002' を通常の人間が読める文字列として書き出すことと同じではありません (最初の文字列は 3 つのヌル終了文字と 10 進値 2 の文字です)。また、フロートのバイナリ表現を文字列にも直接挿入しています。
それが必要な場合は、文字列以外のものを使用して値を格納することをお勧めします ( maybe a std::vector<char>
/ std::vector<unsigned char>
)。例えば:
std::vector<char>& encode_foo(const foo &input) {
// Note that these loops, as @DeadMG pointed out in comments, can be
// more easily accomplished with vector.insert( ... ), e.g.:
// vector.insert(vector.end(), adata, adata + sizeof(input.a));
std::vector<char> data;
char* adata = (char*)&input.a;
char* bdata = (char*)&input.b;
char* cdata = (char*)input.c.data();
for ( int i = 0; i < sizeof(input.a); ++i) {
data.push_back( *adata );
++adata;
}
for ( int j = 0; j < sizeof(input.b); ++j) {
data.push_back( *bdata );
++adata;
}
for ( int k = 0; k < input.c.length(); ++k) {
data.push_back( *cdata );
++cdata;
}
// Now, data contains the absolute minimum binary
// representation of the structure
// There are probably even simpler ways to do this,
// but the 3 loops are very explicit
// And demonstrate what you want.
// You could consider std::copy or memcpy instead if you need
// More flexibility.
return data;
}
foo decode_foo(const std::vector<char>& input) {
// Because you know the structure ahead of time, you can simply reverse the process
// Here, I'll use memcpy to show how that's used too
foo datafoo;
memcpy( datafoo.a, input.data(), sizeof(datafoo.a) );
// Offset by 4 (which is the typical size of an int
memcpy( datafoo.b, input.data() + sizeof(datafoo.a), sizeof(datafoo.b) );
// Now, we offset by 8, and each byte represents a character
// We can memcpy into a std::string's data and null-terminate it as needed
// By calling resize and telling it it's as big as the leftover data
// minus the size of the other structures
int offset = ( sizeof(datafoo.a) + sizeof(datafoo.b) );
int csize = input.size() - offset;
datafoo.c.resize( csize );
memcpy( datafoo.c.input.data(), input.data() + offset, csize );
// Usually, you don't use memcpy with strings,
// but this should do exactly as you want
return datafoo;
}
あなたが要求したように、これは「バイトやスペースを無駄にする」べきではありませんがstd::vector<char>
、バイナリ表現が必要な場合は、おそらくストレージとして使用する必要があることに注意してください。また、protobuffやその他のデータ パッキングおよびデータ転送プロトコルなども調べてください。上記の std::string も使用できますが、上記のいくつかの変更を加えて std::string を使用すると、その文字列が多くのプログラムやルーチンでうまく動作しなくstrings
なることに注意してください。 C++ での数値の 2 進数表現は、それを台無しにしてしまいます。