51.读写结构体.md 5.0 KB
Newer Older
极客江南's avatar
极客江南 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
## 读写结构体

- 结构体中的数据类型不统一,此时最适合用二进制的方式进行读写
- 读写单个结构体

```c
#include <stdio.h>

typedef struct{
    char *name;
    int age;
    double height;
} Person;

int main()
{
    Person p1 = {"lnj", 35, 1.88};
//    printf("name = %s\n", p1.name);
//    printf("age = %i\n", p1.age);
//    printf("height = %lf\n", p1.height);

    FILE *fp = fopen("person.stu", "wb+");
    fwrite(&p1, sizeof(p1), 1, fp);

    rewind(fp);
    Person p2;
    fread(&p2, sizeof(p2), 1, fp);
    printf("name = %s\n", p2.name);
    printf("age = %i\n", p2.age);
    printf("height = %lf\n", p2.height);

    return 0;
}
```

- 读写结构体数组

```c
#include <stdio.h>

typedef struct{
    char *name;
    int age;
    double height;
} Person;

int main()
{
    Person ps[] = {
      {"zs", 18, 1.65},
      {"ls", 21, 1.88},
      {"ww", 33, 1.9}
    };


    FILE *fp = fopen("person.stu", "wb+");
    fwrite(&ps, sizeof(ps), 1, fp);

    rewind(fp);
    Person p;
    while(fread(&p, sizeof(p), 1, fp) > 0){
        printf("name = %s\n", p.name);
        printf("age = %i\n", p.age);
        printf("height = %lf\n", p.height);
    }
    return 0;
}
```

- 读写结构体链表

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

typedef struct person{
    char *name;
    int age;
    double height;
    struct person* next;
} Person;
Person *createEmpty();
void  insertNode(Person *head, char *name, int age, double height);
void printfList(Person *head);
int saveList(Person *head, char *name);
Person *loadList(char *name);

int main()
{

//    Person *head = createEmpty();
//    insertNode(head, "zs", 18, 1.9);
//    insertNode(head, "ls", 22, 1.65);
//    insertNode(head, "ws", 31, 1.78);
//    printfList(head);
//    saveList(head, "person.list");
    Person *head = loadList("person.list");
    printfList(head);
    return 0;
}

/**
 * @brief loadList 从文件加载链表
 * @param name 文件名称
 * @return  加载好的链表头指针
 */
Person *loadList(char *name){
    // 1.打开文件
    FILE *fp = fopen(name, "rb+");
    if(fp == NULL){
        return NULL;
    }
    // 2.创建一个空链表
    Person *head = createEmpty();
    // 3.创建一个节点
    Person *node = (Person *)malloc(sizeof(Person));
    while(fread(node, sizeof(Person), 1, fp) > 0){
        // 3.进行插入
        // 3.1让新节点的下一个节点 等于 头节点的下一个节点
        node->next = head->next;
        // 3.2让头结点的下一个节点 等于 新节点
        head->next = node;

        // 给下一个节点申请空间
        node = (Person *)malloc(sizeof(Person));
    }
    // 释放多余的节点空间
    free(node);
    fclose(fp);
    return head;
}

/**
 * @brief saveList 存储链表到文件
 * @param head 链表头指针
 * @param name 存储的文件名称
 * @return  是否存储成功 -1失败 0成功
 */
int saveList(Person *head, char *name){
    // 1.打开文件
    FILE *fp = fopen(name, "wb+");
    if(fp == NULL){
        return -1;
    }
    // 2.取出头节点的下一个节点
    Person *cur = head->next;
    // 3.将所有有效节点保存到文件中
    while(cur != NULL){
        fwrite(cur, sizeof(Person), 1, fp);
        cur = cur->next;
    }
    fclose(fp);
    return 0;
}
/**
 * @brief printfList 遍历链表
 * @param head 链表的头指针
 */
void printfList(Person *head){
    // 1.取出头节点的下一个节点
    Person *cur = head->next;
    // 2.判断是否为NULL, 如果不为NULL就开始遍历
    while(cur != NULL){
        // 2.1取出当前节点的数据, 打印
        printf("name = %s\n", cur->name);
        printf("age = %i\n", cur->age);
        printf("height = %lf\n", cur->height);
        printf("next = %x\n", cur->next);
        printf("-----------\n");
        // 2.2让当前节点往后移动
        cur = cur->next;
    }
}

/**
 * @brief insertNode 插入新的节点
 * @param head 链表的头指针
 * @param p 需要插入的结构体
 */
void  insertNode(Person *head, char *name, int age, double height){
    // 1.创建一个新的节点
    Person *node = (Person *)malloc(sizeof(Person));
    // 2.将数据保存到新节点中
    node->name = name;
    node->age = age;
    node->height = height;

    // 3.进行插入
    // 3.1让新节点的下一个节点 等于 头节点的下一个节点
    node->next = head->next;
    // 3.2让头结点的下一个节点 等于 新节点
    head->next = node;
}
/**
 * @brief createEmpty 创建一个空链表
 * @return 链表头指针, 创建失败返回NULL
 */
Person *createEmpty(){
    // 1.定义头指针
    Person *head = NULL;
    // 2.创建一个空节点, 并且赋值给头指针
    head = (Person *)malloc(sizeof(Person));
    if(head == NULL){
        return head;
    }
    head->next = NULL;
    // 3.返回头指针
    return head;
}
```

## 

最后,如果有任何疑问,请加微信 **leader_fengy** 拉你进学习交流群。

开源不易,码字不易,如果觉得有价值,欢迎分享支持。