原则:
原则:能够写入,也能够读出并还原。(读出指的是数据的解析和还原)
如果写到文件里,却没有办法读出,那就是一个失败的设计
例如,你2个int变量,值为:12345和6790
失败的存储方法:
char buf[128];
sprintf(“%d%d”, a, b);
fwrite(buf, 1, strlen(buf), fp);
可行的存储方法:
char buf[128];
sprintf(“%d,%d”, a, b); // 以逗号分隔
fwrite(buf, 1, strlen(buf), fp);
如果不以逗号分隔,则无法对数据进行解析。数据白存了!
按字节存储:所有数据,在内存里的表现都是一串字节,因此,只要将这些字节存入即可。
char / short / int : 占1,2,4个字节
float / double: 4,8个字节
数组:
字符数组:
结构体:
指针:另行讨论
- 基本类型的变量
char/short/int/float/double型变量的存储
只需要知道变量地址和大小
// 写入
int a = 0x12345678;
int b = 0x0A0A0A0A;
fwrite(&a, 1, 4, fp); // 4个字节
fwrite(&b, 1, 4, fp); // 4个字节
// 读取
int a ,b;
fread(&a, 1, 4, fp);
fread(&b, 1, 4, fp);
- 数组的存储
地址:即数组名
字节数:手工计算
float arr[4];
fwrite(arr, 1, 4*4 , fp);
// 读取:由于不知道一共存了多个少float,需要循环读取
while(! feof(fp))
{
float a;
if(fread(&a, 1, 4, fp) <= 0)
{
break;
}
}
- 字符数组的存储
(注:这里只是描述一种比较简单的存取方式)
定长方式存取:不论有效长度是多少,统一存储32个字节
char text[32];
fwrite(text, 1, 32, fp);
fread(text, 1, 32, fp);
- 结构体的存储
有两种办法,都比较简单。
第一种办法:直接存取整个结构体。
第二种办法:把每个成员变量依次存储。
struct Student
{
int id;
char name[16];
int scores[3];
};
整体存取
Student s = {201501, “shaofa”, {90,90, 90} };
// 写入
fwrite(&s, 1, sizeof(s), fp);
// 读出
fread(&s, 1, sizeof(s), fp);
把每个成员变量依次分别存取
Student s = {201501, “shaofa”, {90,90, 90} };
// 写入
fwrite(&s.id, 1, sizeof(s.id), fp); // int
fwrite(s.name, 1, sizeof(s.name), fp);// char[]
fwrite(s.score, 1, sizeof(s.score), fp); // int[]
// 读出
fread(&s.id, 1, sizeof(s.id), fp);
fread(s.name, 1, sizeof(s.name), fp);
fread(s.score, 1, sizeof(s.score), fp);
- 指针的存储
指针要么不存储,要么存储它指向的对象的内容
(指针本身没必要存储,它只是一个地址)
struct Car
{
char maker[32]; // 制造商
int price; // 价格
};
struct Citizen
{
char name[32]; // 名字
int deposite; // 存款
Car* car; // NULL时表示没车
};
Car* car = (Car*) malloc(sizeof(Car));
strcpy(car->maker, “Chevrolet”);
car->price = 10;
Citizen who = { “shaofa”, 100};
who.car = car;
如何存储car的信息??显示不能存储指针,因为指针只是一个地址。重启程序之后,要能够从文件中还原出Car的信息才行。
写入文件: 存储car信息
if(who.car != NULL)
{
fwrite(“Y”, 1, 1, fp); // 存入一个字节’Y’
fwrite(who.car->maker, 1, 32, fp);
fwrite(&who.car->price,1, 4, fp);
}
else
{
fwrite(“N”, 1, 1, fp); // 存入一个字节’N’
}
从读文件中读出
char has = ‘N’;
fread(&has, 1, 1, fp);
if(has == ‘Y’) // 先看有没有car的信息
{
Car* car = (Car*) malloc(sizeof(Car));
fread(car->maker, 1, 32, fp);
fread(&car->price, 1, 4, fp);
}
#include <stdio.h> #include <string.h> #include <stdlib.h> struct Student { char gender; // 性别 int id; // id char name[16]; // 年龄 }; struct Car { char maker[32]; // 制造商 int price; // 价格 }; struct Citizen { char name[32]; // 名字 int deposite; // 存款 Car* car; // NULL时表示没车 }; // 存储数据 int save() { const char* filename = "c:/test/aaa.xyz"; FILE* fp = fopen(filename, "wb" ); if(fp == NULL) { printf("failed to open file!\n"); return -1; } Car* car = (Car*) malloc(sizeof(Car)); strcpy(car->maker, "Chevrolet"); car->price = 10; Citizen who = { "shaofa", 100}; who.car = car; fwrite(who.name, 1, 32, fp); fwrite(&who.deposite, 1, 4, fp); if(who.car != NULL) { fwrite("Y", 1, 1, fp); // 存入一个字节'Y' fwrite(who.car->maker, 1, 32, fp); fwrite(&who.car->price,1, 4, fp); } else { fwrite("N", 1, 1, fp); // 存入一个字节'N' } fclose(fp); return 0; } // 读取数据 int load() { const char* filename = "c:/test/aaa.xyz"; FILE* fp = fopen(filename, "rb" ); if(fp == NULL) { printf("failed to open file!\n"); return -1; } Citizen who; fread(who.name, 1, 32, fp); fread(&who.deposite, 1, 4, fp); char has = 'N'; fread(&has, 1, 1, fp); if(has == 'Y') // 先看有没有car的信息 { Car* car = (Car*) malloc(sizeof(Car)); fread(car->maker, 1, 32, fp); fread(&car->price, 1, 4, fp); who.car = car; } else { who.car = NULL; } fclose(fp); return 0; } int main() { //save(); load(); return 0; }