警告:以下代码使用当前平台的字节序来处理数据。如果您将其发送到可能没有相同字节序和其他相关架构参数的其他平台,请小心。
我将假设您了解您正在做的是将浮点数的 4 个字节放入字符串的内存中,而不是浮点数的字符串表示。例如,对于值为 2 的整数,您将 char 值 '\0'、'\0'、'\0'、'\2' 放入字符串中。这与将 '002' 写为常规的人类可读字符串不同(第一个是 3 个空终止符加上一个十进制值为 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
预计为 null-终止,并且 C++ 中数字的二进制表示将为您彻底解决这个问题。