2012-04-05 106 views
2

我正在將結構序列化爲字節流。我的方法很簡單: 以小端順序打包所有整數並複製包括空終止符的字符串。另一方必須靜態知道如何解壓字節流,沒有額外的元數據。序列化字符串C

我的問題是,我不知道如何處理NULL指針?

我需要發送一些內容,因爲流中沒有額外的元數據。

我考慮以下兩種選擇:

  1. 寄「\ 0」,使在接收側把它解釋爲NULL在任何情況下

  2. 寄「\ 0」,使(分配一個字節)

  3. 發送表示char * str == NULL的特殊字符,例如ETX,EOT,EM?

你覺得呢?

回答

4

它看起來像你目前正試圖告訴接收端通過傳遞一個特殊字符來達到序列化字符串的末尾。有一百萬個案例可以用這個來解決你的問題:

如果你的結構體包含一個等於那個特殊字符的字節,該怎麼辦?用另一個特殊字符逃脫它。如果你的結構包含一個與你的特殊字符相同的轉義字符的字節序列,那麼檢查它呢?

是的,它是可行的,但我認爲這不是一個很好的解決方案,你將不得不編寫一個解析器來查找轉義字符,然後任何稍後看看代碼的人都會花費兩個小時嘗試瞭解正在發生的事情。

(t1; dr)相反...只是使序列化字符串的前32位等於字符串中的字節數。這隻需要每個序列化4字節,解決了所有問題,您不必編寫解析器或擔心特殊字符,並且使下一個可以讀取代碼的人更容易!

編輯

感謝JeremyP我剛剛意識到,我並沒有真正回答你的問題。每個字符串發送一個這些傢伙:

struct s_str { bool is_null; int size; char * str; };

如果它爲空,只需將is_null設置爲true,並且您不必擔心其他兩個。 如果大小爲零,請將is_null設置爲false並將大小設置爲零。 如果str只包含'\ 0',設置is_null爲false,大小爲1,str [0]爲'\ 0'

在我看來,這可能不是最有效的內存方式可能會以某種方式在某個地方保存一個字節),但是在你正在做的事情中肯定很清楚,並且下一個出現的人會再這樣做。

+0

爲什麼downvote? – 2012-04-05 10:56:53

+0

這不是我投下的票,但我不認爲你已經回答了這個問題,即如何編碼一個空指針(零長度字符串不是空字符串)。我會做一個特殊的長度值。 – JeremyP 2012-04-05 11:05:17

+0

您先生是正確的。在編輯路上。非常感謝你! – 2012-04-05 11:13:12

2

不要這樣做。使用一些額外的字節來存儲長度並與您的數據字符串連接。接收端可以檢查它的長度,知道它應該讀入他的本地緩衝區。

2

它取決於協議中指針的重要性。 如果指針很重要,即收件人需要知道如何重建結構,那麼你需要發送一些東西。它可以是一個0 /非零的字節來指示存在,也可以是一個指示指針指向的字節數的整數。

例子: 結構美孚{ INT *改編, 字符*文本 }

結構美孚可序列化這樣的:

<arr length>< arr ><text length><text> 
    4 bytes n bytes 4 bytes  n bytes 
2

我會建議你使用現有的庫序列化。我現在可以想到兩個:tpl和gwlib的gwser

關於tpl

您可以使用第三方物流來存儲和快速,輕鬆地重新加載你的C數據。 Tpl使用文件,內存緩衝區和文件描述符,因此它適合用作文件格式,IPC消息格式或任何需要存儲和檢索數據的場景的 。

關於gwlib,請參閱鏈接,它不是很詳細,但它提供了幾個用法示例。