【问题标题】:Serializing strings in C在 C 中序列化字符串
【发布时间】:2012-04-05 10:21:09
【问题描述】:

我正在将结构序列化为字节流。我的方法很简单: 以小端顺序打包所有整数并复制包括空终止符的字符串。对方必须静态知道如何解压字节流,没有额外的元数据。

我的问题是,我不知道如何处理 NULL 指针?

我需要发送一些东西,因为流中没有额外的元数据。

我考虑了以下两个选项:

  1. 发送一个'\0'并让接收方在任何情况下都将其解释为NULL

  2. 发送一个'\0'并让接收方在任何情况下都将其解释为'\0'(分配一个字节)

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

你怎么看?

【问题讨论】:

    标签: c string serialization null deserialization


    【解决方案1】:

    看起来您当前正试图通过向接收端传递一个特殊字符来告诉接收端已到达序列化字符串的末尾。有一百万个案例会让你大吃一惊:

    如果你的结构包含一个等于那个特殊字符的字节怎么办。用另一个特殊字符转义它。如果您的结构包含等于您的转义字符后跟您的特殊字符的字节序列,也要检查吗?

    是的,这是可行的,但我认为这不是一个很好的解决方案,您必须编写一个解析器来查找转义字符,然后任何稍后查看代码的人都将花费两个小时试图弄清楚发生了什么事。

    (tl;dr) 相反... 只需使序列化字符串的前 32 位等于字符串中的字节数。每次序列化只需 4 个字节,解决了所有问题,您不必编写解析器或担心特殊字符,并且会让下一个阅读您的代码的人更容易!

    编辑

    感谢 JeremyP,我刚刚意识到我并没有真正回答您的问题。为每个字符串发送其中一个:

    结构 s_str { 布尔 is_null; 整数大小; 字符* str; };

    如果它为 null,只需将 is_null 设置为 true,您就不必担心其他两个。 如果它的大小为零,请将 is_null 设置为 false 并将大小设置为零。 如果 str 只包含一个 '\0',则将 is_null 设置为 false,将 size 设置为 1,并将 str[0] 设置为 '\0'

    在我看来,这可能不是最节省内存的方式(您可能会以某种方式在某处保存一个字节),但您在做什么绝对很清楚,并且下一个出现的人会再次喜欢这个更多。

    【讨论】:

    • 投反对票的不是我,但我认为您没有回答问题,即如何编码空指针(零长度字符串不是空字符串)。我会用一个特殊的长度值来做。
    【解决方案2】:

    不要这样做。使用一些额外的字节来存储长度并与您的数据字符串连接。接收端可以检查长度以了解它应该读入他的本地缓冲区的长度。

    【讨论】:

      【解决方案3】:

      这取决于你的协议中指针的重要性。 如果指针很重要,即接收者需要知道如何重建结构,那么你需要发送一些东西。它可以是一个带有 0/非零的字节表示存在,也可以是一个整数,表示指针指向的字节数。

      示例: 结构富{ int *arr, 字符 *文本 }

      Struct Foo 可以这样序列化:

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

      【讨论】:

        【解决方案4】:

        我建议您使用现有的库进行序列化。目前我能想到两个:tpl 和 gwlib 的 gwser

        关于tpl

        您可以使用 tpl 快速轻松地存储和重新加载您的 C 数据。 Tpl 适用于文件、内存缓冲区和文件描述符,因此它是 适合用作文件格式、IPC 消息格式或任何场景 您需要存储和检索数据的位置。

        关于gwlib,见链接,不是很冗长,但提供了一些使用示例。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-09-13
          • 2012-05-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-09-02
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多