前言

  C中对序列化讨论少, 因为很多传输的内容都有自己解析的轮子. 对于序列化本质是统一编码, 统一解码的方式.

本文探讨是一种简单的序列化方案. 保证不同使用端都能解析出正确结果.

在文章一开始, 看一个最简单的序列化代码 如下

#include <stdio.h>
#include <stdlib.h>

#define _INT_NAME        (64)
#define _STR_TXT        "student.struct"

struct student {
    int id;
    char sex;
    int age;
    char name[_INT_NAME + 1];
    double high;
    double weight;
};

// struct student 结构体序列化到文件的方法
static void _student_serialize(struct student* stu, FILE* txt) {
    fprintf(txt, "%d %c %d %s %lf %lf ", stu->id, stu->sex, 
        stu->age, stu->name, stu->high, stu->weight);
}

// struct student 结构体反序列化
static void _student_deserialize(struct student* stu, FILE* txt) {
    fscanf(txt, "%d %c %d %s %lf %lf ", &stu->id, &stu->sex,
        &stu->age, stu->name, &stu->high, &stu->weight);
}

// 简单打印数据
static void _student_print(struct student* stu) {
    static int _idx;

    printf("%d: %d %c %d %s %lf %lf \n", _idx++, stu->id,
        stu->sex, stu->age, stu->name, stu->high, stu->weight);
}

/*
 * 一种最简单的通用序列化方法
 */
int main(int argc, char* argv[]) {
    
    FILE* txt = fopen(_STR_TXT, "wb+");
    if (NULL == txt) {
        fprintf(stderr, "fopen " _STR_TXT " error!\n");
        return -1;
    }

    // 这里写入数据
    struct student stu = { 0, 0, 23, "鸣人", 172.23, 64.05 };
    _student_print(&stu);

    // 这里序列化并写入数据到文件
    _student_serialize(&stu, txt);

    // 我们读取这个文件, 先设置文件指针到文件开头
    fseek(txt, 0, SEEK_SET);

    // 开始读取数据
    struct student ts;
    _student_deserialize(&ts, txt);
    _student_print(&ts);

    fclose(txt);
    system("pause");
    return 0;
}

 

本质在  自定义编码解码,并利用 scanf和printf 对映关系

// struct student 结构体序列化到文件的方法
static void _student_serialize(struct student* stu, FILE* txt) {
    fprintf(txt, "%d %c %d %s %lf %lf ", stu->id, stu->sex, 
        stu->age, stu->name, stu->high, stu->weight);
}

// struct student 结构体反序列化
static void _student_deserialize(struct student* stu, FILE* txt) {
    fscanf(txt, "%d %c %d %s %lf %lf ", &stu->id, &stu->sex,
        &stu->age, stu->name, &stu->high, &stu->weight);
}

 

运行结果 如下:

C基础  数据序列化简单使用和讨论

通过这种实现, 是跨平台的. 因为C实现标准和自己定义协议支持

 "%d %c %d %s %lf %lf "

 

最后我们还会讨论这种情况.

 

正文

1. 一次失败扩展 fscanf -> fread ; fprintf -> fwrite

测试如下, 在window上测试代码 main.c

#include <stdio.h>
#include <stdlib.h>

#define _INT_NAME        (64)
#define _STR_TXT        "student.struct"

struct student {
    int id;
    char sex;
    int age;
    char name[_INT_NAME + 1];
    double high;
    double weight;
};

// struct student 结构体序列化到文件的方法
static void _student_serialize(struct student* stu, FILE* txt) {
    fwrite(stu, sizeof(*stu), 1, txt);
}

// struct student 结构体反序列化
static void _student_deserialize(struct student* stu, FILE* txt) {
    fread(stu, sizeof(*stu), 1, txt);
}

// 简单打印数据
static void _student_print(struct student* stu) {
    static int _idx;

    printf("%d: %d %c %d %s %lf %lf \n", _idx++, stu->id,
        stu->sex, stu->age, stu->name, stu->high, stu->weight);
}

/*
* 一种最简单的通用序列化方法
*/
int main(int argc, char* argv[]) {
    FILE* txt = fopen(_STR_TXT, "wb+");
    if (NULL == txt) {
        fprintf(stderr, "fopen " _STR_TXT " error!\n");
        return -1;
    }

    // 这里写入数据
    struct student stu = { 0, 0, 23, "鸣人", 172.23, 64.05 };
    _student_print(&stu);

    // 这里序列化并写入数据到文件
    _student_serialize(&stu, txt);

    // 我们读取这个文件, 先设置文件指针到文件开头
    fseek(txt, 0, SEEK_SET);

    // 开始读取数据
    struct student ts;
    _student_deserialize(&ts, txt);
    _student_print(&ts);

    fclose(txt);
    system("pause");
    return 0;
}
View Code

相关文章: