我需要将各种结构序列化到一个文件中。如果可能的话,我希望文件是纯 ASCII。我可以为每个结构编写某种序列化程序,但是有数百个包含我想准确表示float
的 s 和s 。double
我不能使用第三方序列化库,也没有时间编写数百个序列化器。
如何以 ASCII 安全的方式序列化这些数据?也请流,我讨厌 C-style 的外观printf("%02x",data)
。
我需要将各种结构序列化到一个文件中。如果可能的话,我希望文件是纯 ASCII。我可以为每个结构编写某种序列化程序,但是有数百个包含我想准确表示float
的 s 和s 。double
我不能使用第三方序列化库,也没有时间编写数百个序列化器。
如何以 ASCII 安全的方式序列化这些数据?也请流,我讨厌 C-style 的外观printf("%02x",data)
。
我在网上找到了这个解决方案,它解决了这个问题:
https://jdale88.wordpress.com/2009/09/24/c-anything-tofrom-a-hex-string/
转载如下:
#include <string>
#include <sstream>
#include <iomanip>
// ------------------------------------------------------------------
/*!
Convert a block of data to a hex string
*/
void toHex(
void *const data, //!< Data to convert
const size_t dataLength, //!< Length of the data to convert
std::string &dest //!< Destination string
)
{
unsigned char *byteData = reinterpret_cast<unsigned char*>(data);
std::stringstream hexStringStream;
hexStringStream << std::hex << std::setfill('0');
for(size_t index = 0; index < dataLength; ++index)
hexStringStream << std::setw(2) << static_cast<int>(byteData[index]);
dest = hexStringStream.str();
}
// ------------------------------------------------------------------
/*!
Convert a hex string to a block of data
*/
void fromHex(
const std::string &in, //!< Input hex string
void *const data //!< Data store
)
{
size_t length = in.length();
unsigned char *byteData = reinterpret_cast<unsigned char*>(data);
std::stringstream hexStringStream; hexStringStream >> std::hex;
for(size_t strIndex = 0, dataIndex = 0; strIndex < length; ++dataIndex)
{
// Read out and convert the string two characters at a time
const char tmpStr[3] = { in[strIndex++], in[strIndex++], 0 };
// Reset and fill the string stream
hexStringStream.clear();
hexStringStream.str(tmpStr);
// Do the conversion
int tmpValue = 0;
hexStringStream >> tmpValue;
byteData[dataIndex] = static_cast<unsigned char>(tmpValue);
}
}
这可以很容易地适应读/写文件流,尽管仍然需要stringstream
使用 in ,但fromHex
必须一次完成两个读取字符的转换。
无论如何,您都需要每种结构类型的序列化代码。您不能只是将结构位复制到外部世界,并期望它能够工作。
如果您想要纯 ascii,请不要使用十六进制。对于序列化float
and double
,将输出流设置为科学,将精度设置为 8float
和 16
double
。(它会多占用几个字节,但它实际上会起作用。)
其余的:如果结构写得很干净,根据一些内部编程指南,并且只包含基本类型,你应该能够直接解析它们。否则,最简单的解决方案通常是设计一种非常简单的描述符语言,描述其中的每个结构,并在其上运行代码生成器以获取序列化代码。