2013-07-03 81 views
1

我需要序列化各種結構到一個文件。 如果可能,我希望這些文件是純ASCII。我可以爲每個結構體編寫某種序列化器,但有數百個和許多包含float s和double s,我想準確地表示它們。讀寫二進制對象爲十六進制?

我不能使用第三方的序列化庫,我沒有時間寫數百個serializiers。

如何將ASCII數據安全地串行化? 還有流請,我討厭C型printf("%02x",data)的外觀。

+1

爲什麼你需要這個?如果你只是將它轉換爲十六進制,那麼它仍然是POD,只是十六進制形式。如果你想把它作爲ASCII流發送,那麼你可以直接從存儲器中將二進制數據轉換成Base64。 – Devolus

回答

2

我發現這個解決方案在網上,它解決了眼前這個問題:

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); 
    } 
} 

這可以很容易地適應讀/寫文件流,雖然在fromHex中使用的stringstream仍然是必需的,但轉換必須一次完成兩個讀取字符。

0

任何你這樣做的方式,你將需要每個結構類型的 的序列化代碼。你不能只將位結構複製到外部世界,並期望它能夠工作。

如果你想純粹的ASCII,不要打擾與十六進制。對於 序列化floatdouble,將輸出流設置爲 科學,並將精度設置爲8,對於float和16對於 double。 (這將需要幾個字節,但它實際上 工作。)

對於剩下的:如果該結構被清晰地寫入,根據 一些內部編程指南和只有包含基本 類型,你應該能夠直接解析它們。否則, 最簡單的解決方案通常是設計一個非常簡單的描述符語言,描述其中的每個結構,並在其上運行一個代碼 生成器以獲取序列化代碼。

相關問題