redis怎么存c语言嵌套结构体

不及物动词 其他 60

回复

共3条回复 我来回复
  • 不及物动词的头像
    不及物动词
    这个人很懒,什么都没有留下~
    评论

    在使用Redis存储C语言嵌套结构体时,我们可以采用以下两种常见的方法:

    方法一:将嵌套结构体转换为字符串

    1. 将嵌套结构体的各个字段按照一定的规则拼接成一个字符串。
    2. 使用Redis的字符串类型存储该字符串。

    示例代码如下:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <hiredis/hiredis.h>
    
    typedef struct {
        int id;
        char name[20];
    } InnerStruct;
    
    typedef struct {
        int outerId;
        InnerStruct inner;
    } OuterStruct;
    
    char *structToString(OuterStruct s) {
        char *result = malloc(sizeof(char) * 50);
        sprintf(result, "%d:%d:%s", s.outerId, s.inner.id, s.inner.name);
        return result;
    }
    
    OuterStruct stringToStruct(char *str) {
        OuterStruct s;
        char *token = strtok(str, ":");
        s.outerId = atoi(token);
        token = strtok(NULL, ":");
        s.inner.id = atoi(token);
        token = strtok(NULL, ":");
        strcpy(s.inner.name, token);
        return s;
    }
    
    int main() {
        OuterStruct originalStruct = {1, {2, "John"}};
        
        // 将嵌套结构体转换为字符串
        char *str = structToString(originalStruct);
        
        // 使用Redis存储字符串
        redisContext *redis = redisConnect("127.0.0.1", 6379);
        redisReply *reply = redisCommand(redis, "SET mystruct \"%s\"", str);
        
        // 从Redis中获取字符串
        reply = redisCommand(redis, "GET mystruct");
        printf("String from Redis: %s\n", reply->str);
        
        // 将字符串转换回嵌套结构体
        OuterStruct convertedStruct = stringToStruct(reply->str);
        printf("Converted Struct: outerId=%d, inner.id=%d, inner.name=%s\n", 
                convertedStruct.outerId, convertedStruct.inner.id, convertedStruct.inner.name);
        
        // 释放资源
        free(str);
        freeReplyObject(reply);
        redisFree(redis);
        
        return 0;
    }
    

    方法二:将嵌套结构体序列化为字节数组

    1. 使用序列化框架(如MessagePack、Protobuf等)将嵌套结构体序列化为字节数组。
    2. 使用Redis的二进制类型(如字符串、列表、哈希表等)存储该字节数组。

    示例代码如下,以使用MessagePack为例:

    #include <stdio.h>
    #include <stdlib.h>
    #include <msgpack.h>
    #include <hiredis/hiredis.h>
    
    typedef struct {
        int id;
        char name[20];
    } InnerStruct;
    
    typedef struct {
        int outerId;
        InnerStruct inner;
    } OuterStruct;
    
    msgpack_sbuffer* structToSbuffer(OuterStruct s) {
        msgpack_sbuffer *sbuf = msgpack_sbuffer_new();
        msgpack_packer *pk = msgpack_packer_new(sbuf, msgpack_sbuffer_write);
        
        msgpack_pack_int(pk, s.outerId);
        msgpack_pack_int(pk, s.inner.id);
        msgpack_pack_raw(pk, strlen(s.inner.name));
        msgpack_pack_raw_body(pk, s.inner.name, strlen(s.inner.name));
        
        return sbuf;
    }
    
    OuterStruct sbufferToStruct(msgpack_sbuffer *sbuf) {
        OuterStruct s;
        msgpack_unpacker unpacker;
        
        msgpack_unpacker_init(&unpacker, MSGPACK_UNPACKER_INIT_BUFFER_SIZE);
        msgpack_unpacker_reserve_buffer(&unpacker, sbuf->size);
        memcpy(msgpack_unpacker_buffer(&unpacker), sbuf->data, sbuf->size);
        msgpack_unpacker_buffer_consumed(&unpacker, sbuf->size);
        
        msgpack_object deserialized;
        msgpack_unpack(&unpacker, sbuf->data, sbuf->size, NULL, &deserialized);
        
        s.outerId = deserialized.via.array.ptr[0].via.i64;
        s.inner.id = deserialized.via.array.ptr[1].via.i64;
        memcpy(s.inner.name, 
               deserialized.via.array.ptr[2].via.raw.ptr, 
               deserialized.via.array.ptr[2].via.raw.size);
        
        return s;
    }
    
    int main() {
        OuterStruct originalStruct = {1, {2, "John"}};
        
        // 将嵌套结构体序列化为字节数组
        msgpack_sbuffer *sbuf = structToSbuffer(originalStruct);
        
        // 使用Redis存储字节数组
        redisContext *redis = redisConnect("127.0.0.1", 6379);
        redisReply *reply = redisCommand(redis, "SET mystruct %b", sbuf->data, sbuf->size);
        
        // 从Redis中获取字节数组
        reply = redisCommand(redis, "GET mystruct");
        printf("Bytes from Redis: ");
        for (size_t i = 0; i < reply->len; i++) {
            printf("%02x ", reply->str[i]);
        }
        printf("\n");
        
        // 将字节数组反序列化为嵌套结构体
        msgpack_sbuffer newSbuf;
        newSbuf.size = reply->len;
        newSbuf.data = (char*)reply->str;
        OuterStruct convertedStruct = sbufferToStruct(&newSbuf);
        printf("Converted Struct: outerId=%d, inner.id=%d, inner.name=%s\n", 
                convertedStruct.outerId, convertedStruct.inner.id, convertedStruct.inner.name);
        
        // 释放资源
        msgpack_sbuffer_free(sbuf);
        freeReplyObject(reply);
        redisFree(redis);
        
        return 0;
    }
    

    以上两种方法中,字符串方法适用于将嵌套结构体存储为可读的字符串形式,而字节数组方法则适用于将嵌套结构体存储为二进制形式。选择哪种方法取决于具体的需求和使用场景。

    1年前 0条评论
  • worktile的头像
    worktile
    Worktile官方账号
    评论

    Redis是一个内存数据存储系统,它支持存储各种数据类型,包括字符串、哈希、列表、集合、有序集合等。如果想要在Redis中存储C语言的嵌套结构体,可以采用以下几种方法:

    1. 序列化存储:将嵌套结构体转换为字符串,并使用Redis的字符串类型进行存储。可以使用标准的C库函数(如sprintf、memcpy等)将嵌套结构体转换为字符串,然后使用Redis的字符串类型进行存储。这种方法的优点是简单易懂,但缺点是需要进行序列化和反序列化操作,可能会增加一些额外的开销。

    2. 使用哈希类型:将嵌套结构体的每个字段作为哈希的key-value对进行存储。可以使用Redis的哈希类型(hash)来存储嵌套结构体。将嵌套结构体的每个字段作为哈希的字段(field),对应的值作为字段的值进行存储。这种方法的优点是可以实现类似数据库的查询功能,但缺点是无法直接获取整个嵌套结构体。

    3. 使用有序集合类型:将每个嵌套结构体作为有序集合的一个元素进行存储。可以使用Redis的有序集合类型(sorted set)来存储嵌套结构体。将每个嵌套结构体作为一个有序集合的成员,成员的分数可以用来排序或者作为索引。这种方法的优点是可以方便地进行排序和范围查询,缺点是无法直接获取整个嵌套结构体。

    4. 自定义数据结构:可以自定义一个数据结构,并使用Redis的字符串类型进行存储。将嵌套结构体的每个字段拼接成一个字符串,然后使用Redis的字符串类型进行存储。这种方法的优点是自定义灵活度高,但缺点是需要额外的序列化和反序列化操作。

    5. 使用Redis模块:可以使用Redis的扩展模块(Redis Module)来自定义数据类型,并直接存储嵌套结构体。Redis模块允许开发者根据需求自定义数据类型,并将其作为原生的Redis数据类型进行存储和操作。这种方法的优点是灵活性高,缺点是开发和维护成本相对较高。

    需要注意的是,无论选择哪种方法,在存储和读取嵌套结构体时都需要进行序列化和反序列化操作,以保证数据在存储和传输过程中的完整性和一致性。另外,根据实际情况选择合适的方法,并根据需求进行性能和安全性的评估。

    1年前 0条评论
  • fiy的头像
    fiy
    Worktile&PingCode市场小伙伴
    评论

    要在Redis中存储C语言嵌套结构体,可以通过以下方法操作:

    1. 定义嵌套结构体:
      首先,需要定义C语言中的嵌套结构体。例如,假设我们有以下嵌套结构体:
    typedef struct Teacher {
        char name[20];
        int age;
        char title[20];
    } Teacher;
    
    typedef struct Student {
        char name[20];
        int age;
        char grade[10];
    } Student;
    
    typedef struct Course {
        char name[50];
        Student student;
        Teacher teacher;
    } Course;
    
    1. 将嵌套结构体转换为Redis存储格式:
      Redis是一个键值对存储系统,它可以存储字符串、列表、哈希等数据结构。为了将嵌套结构体存储在Redis中,我们需要将其转换为合适的存储格式。
      对于嵌套结构体,一种常见的方法是将其转换为JSON字符串,并将其作为Redis中的一个键值对的值存储。为此,我们可以使用一个库,如 cJSON 来进行 JSON 的序列化和反序列化。

    2. 序列化嵌套结构体:
      首先,我们需要将嵌套结构体序列化为一个JSON字符串。可以按照以下步骤进行:

      • 导入 cJSON 库,该库提供了一些函数用于序列化和反序列化 JSON。
      • 创建一个空的 cJSON 对象。
      • 使用 cJSON_CreateObject 创建一个嵌套的 cJSON 对象,该对象将存储课程信息。
      • 使用 cJSON_AddItemToObject 函数将其他 cJSON 对象添加为子对象到嵌套 cJSON 对象中。
      • 使用 cJSON_AddStringToObject 或 cJSON_AddNumberToObject 函数将结构体的成员添加为对象的键值对。
      • 使用 cJSON_Print 函数将 cJSON 对象转换为 JSON 字符串。
      • 释放 cJSON 对象的内存。

      按照上述步骤,可以编写以下样例代码将 Course 结构体序列化为 JSON 字符串:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "cJSON.h"
    
    char* serializeCourse(Course course) {
        cJSON* courseJson = cJSON_CreateObject();
        cJSON* studentJson = cJSON_CreateObject();
        cJSON* teacherJson = cJSON_CreateObject();
    
        cJSON_AddStringToObject(studentJson, "name", course.student.name);
        cJSON_AddNumberToObject(studentJson, "age", course.student.age);
        cJSON_AddStringToObject(studentJson, "grade", course.student.grade);
    
        cJSON_AddStringToObject(teacherJson, "name", course.teacher.name);
        cJSON_AddNumberToObject(teacherJson, "age", course.teacher.age);
        cJSON_AddStringToObject(teacherJson, "title", course.teacher.title);
    
        cJSON_AddStringToObject(courseJson, "name", course.name);
        cJSON_AddItemToObject(courseJson, "student", studentJson);
        cJSON_AddItemToObject(courseJson, "teacher", teacherJson);
    
        char* jsonString = cJSON_Print(courseJson);
    
        cJSON_Delete(courseJson);
    
        return jsonString;
    }
    
    1. 存储嵌套结构体数据到Redis:
      现在,我们已经将嵌套结构体序列化为JSON字符串,接下来需要将其存储到Redis中。可以按照以下步骤进行:

      • 连接到Redis服务器。
      • 使用 SET 命令将序列化的JSON字符串作为值存储在Redis中的键中。

      按照上述步骤,可以编写以下样例代码将序列化的 Course 结构体存储到Redis中:

    #include <hiredis/hiredis.h>  // Redis C 客户端库
    
    void storeCourseDataToRedis(const char* key, const char* value) {
        redisContext* context = redisConnect("localhost", 6379);  // 连接到 Redis 服务器
        if (context == NULL || context->err) {
            if (context) {
                printf("Error: %s\n", context->errstr);
                redisFree(context);
            } else {
                printf("Can't allocate redis context\n");
            }
            return;
        }
    
        redisReply* reply = redisCommand(context, "SET %s %s", key, value);  // 将JSON字符串存储到Redis
        if (reply == NULL) {
            printf("Failed to store the data in Redis\n");
        }
    
        freeReplyObject(reply);
        redisFree(context);
    }
    
    1. 从Redis检索嵌套结构体数据:
      如果想要从Redis中检索嵌套结构体数据,可以按照以下步骤进行:

      • 连接到Redis服务器。
      • 使用 GET 命令从Redis检索键的值。
      • 使用 cJSON_Parse 函数解析JSON字符串为 cJSON 对象。
      • 使用 cJSON_GetObjectItem 函数从 cJSON 对象中检索各个成员的值。
      • 将 cJSON 对象转换为嵌套结构体。

      按照上述步骤,可以编写以下样例代码从Redis中检索存储的 Course 结构体:

    Course deserializeCourse(const char* jsonString) {
        Course course;
        cJSON* courseJson = cJSON_Parse(jsonString);
    
        cJSON* studentJson = cJSON_GetObjectItemCaseSensitive(courseJson, "student");
        cJSON* teacherJson = cJSON_GetObjectItemCaseSensitive(courseJson, "teacher");
    
        strncpy(course.student.name, cJSON_GetObjectItemCaseSensitive(studentJson, "name")->valuestring, sizeof(course.student.name));
        course.student.age = cJSON_GetObjectItemCaseSensitive(studentJson, "age")->valueint;
        strncpy(course.student.grade, cJSON_GetObjectItemCaseSensitive(studentJson, "grade")->valuestring, sizeof(course.student.grade));
    
        strncpy(course.teacher.name, cJSON_GetObjectItemCaseSensitive(teacherJson, "name")->valuestring, sizeof(course.teacher.name));
        course.teacher.age = cJSON_GetObjectItemCaseSensitive(teacherJson, "age")->valueint;
        strncpy(course.teacher.title, cJSON_GetObjectItemCaseSensitive(teacherJson, "title")->valuestring, sizeof(course.teacher.title));
    
        strncpy(course.name, cJSON_GetObjectItemCaseSensitive(courseJson, "name")->valuestring, sizeof(course.name));
    
        cJSON_Delete(courseJson);
    
        return course;
    }
    

    以上就是将C语言嵌套结构体存储在Redis中的方法。首先,我们需要将嵌套结构体序列化为JSON字符串,然后将其作为值存储在Redis中的键中。在需要检索数据时,我们可以从Redis中检索JSON字符串,并将其反序列化为嵌套结构体。

    1年前 0条评论
注册PingCode 在线客服
站长微信
站长微信
电话联系

400-800-1024

工作日9:30-21:00在线

分享本页
返回顶部