【问题标题】:Serializing string in c在c中序列化字符串
【发布时间】:2017-11-27 16:02:34
【问题描述】:

我正在尝试序列化字节流中的结构。基本上,我必须使用这种类型的结构:

typedef struct { 
   unsigned a, b;
   unsigned c, d;
} struct_t;

我必须将此结构的元素转换为字符串的字符。例如,我得到以下内容:

struct_t *structure; /* pointer to the structure due to be converted */
char *s; /* array of char where to write the string result of the conversion */
int len; /* lenght of the array s */

我在理解如何通过序列化来做到这一点时遇到了一些问题。 提前感谢您的帮助。

【问题讨论】:

  • 看来您需要将结构的内容转换为可打印的字符串。想出一个格式,用snprintf写字符串。
  • 序列化的数据会用到哪里?你想要多大的灵活性?有无穷无尽的可能性——而且它们大多非常简单。你需要标记开始和结束吗? snprintf(buf, len, "[%u,%u,%u,%u]", structure->a, structure->b, structure->c, structure->d) 可能就足够了(如果您检查输出没有被截断 - 捕获并测试来自 snprintf() 的返回值)。
  • wikipedia 很好地解释了序列化。现在我会远离 XML,而是使用 JSON 库(网络上到处都在讨论优缺点)。
  • 当心只是通过将其转换为字节指针来进行序列化。如果您最终在具有不同字节序的系统上读回数据,您可能会遇到字节序问题。
  • 我要做的是实现一个函数,其标题如下:char * struct_to_string (struct_t* structure, char* s, int len); 这个函数将结构表示为字符串。如果转换成功,\retval 必须为 s,否则 \retval 必须为 NULL。我正在开发一个项目,该项目需要将字符串(称为字符串 [i])转换为结构(完成,它工作正常),然后再次将此结构转换为新字符串,这显然是与string[i]基本相同。

标签: c arrays string serialization structure


【解决方案1】:

鉴于要求,这似乎可行,正如我在comment 中提到的那样:

char *serialize_struct_t(const struct_t structure, char *s, int len)
{
    if (snprintf(s, len, "[%u,%u,%u,%u]", structure->a, structure->b,
                 structure->c, structure->d) < len)
        return s;
    return 0;
}

这会产生像[23,45,67,90] 这样的输出。显然,还有许多其他可能的格式,用空格作为分隔符,没有开始或结束标记。任何此类更改都需要对下面显示的反序列化代码进行相应的更改。

假设您使用上面显示的格式,您可以使用如下函数反序列化此类数据:

int deserialize(const char *buffer, struct_t *structure)
{
    char c;
    int  len;
    if (sscanf(buffer, " [%u ,%u ,%u ,%u %c%n", &structure->a,
               &structure->b, &structure->c, &structure->d, &c, &len) != 5 ||
        c != ']')
        return -1;
    return len;
}

你可以讨论接口的细节,但是如果字符串与serialize_struct_t() 的输出不匹配,或者匹配的字符串的长度不匹配,它会返回-1(这样你就知道从哪里继续搜索)。格式中的空格表示可选的空格; %u 无论如何都会跳过可选的白色。 %c 允许您在末尾检测到 ] 以外的其他内容;如果您在格式字符串中使用 litera ],您将无法发现问题。 %n 告诉你它匹配的偏移量,它位于末尾。不计算%n 转换。

显然,根据选择的序列化格式,您需要更改反序列化扫描器以匹配。

这就是序列化和反序列化的工作方式——序列化格式(应该严格定义)控制反序列化代码需要识别的内容。反序列化代码可以更灵活(例如,您可以反对显示的格式字符串中的所有空格,但这会使接受的格式更加僵化),但肯定应该识别序列化代码产生的任何内容。请参阅 Wikipedia 上的 Robustness Principle,即 Postel 定律。

【讨论】:

    猜你喜欢
    • 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
    相关资源
    最近更新 更多