主要:数据存储(原则:保证能写入,也能读出并还原)
方法:按字节存储
首先都是读取路径,并正确打开
main函数中输入以下代码:
int main()
{
const char* filename = "C:/Users/hhh/Desktop/aa.txt";
FILE* fp = fopen(filename, "wb"); //wb为覆盖写入,ab为追加写入,rb为读取
............//开始写入要存储或读取的代码
fclose(fp);
return 0;
}
1、基本类型的存取(eg:int ,short,char)
存储操作,比如:
int a = 0x12345678;
fwrite(&a,1,4,fp); //一次从a中读取四个字节,存储在fp中
读取操作,比如:
int b;
fread(&b,1,4,fp); //每次从fp中读取4个字节,存在缓存b中
2、数组的存取
存储操作,比如:
float arr[4] = {1.1f,1.2f,1.3f,1.4f};
fwrite(arr,1,4*4,fp);
读取操作,比如:
float arr[128];
int count = 0;
while(!feof (fp))//因为不知道数组的具体长度,利用feof函数进行判断
{
float a;
if(fread(&a,1,4,fp)<=0)
{
break;
}
printf("read:%.2lf \n",a);
arr[count] = a; //将读取的东西保存在arr中,也可不保存
count++;
}
3、字符数组的存取(采用定长方式存取)
存储操作,比如:
char text[32] = "hellowrold";
fwrite(text,1,32,fp);
读取操作,比如:
char buf[32];
fread(buf,1,32,fp);
4、结构体的存取
定义一个结构体:
struct Student
{
int id;
char name[32];
int score[3];
}
方法一:整体存取
存储操作,比如:
Student s = {20180530,"xiaoyu",{90,90,90}};
fwrite(&s,1,sizeof(s),fp);
读取操作,比如:
fread(&s,1,sizof(s),fp);
方法二:分段存取
存取操作,比如:
fwrite(&s.id,1,sizeof(s.id),fp);
fread(&s.id,1,sizeof(s.id),fp);
5、指针的存取
指针的存取有点难,这里给出全代码。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct Car
{
char marker[32];
int price;
};
struct Citizen
{
char name[16];
int deposize;
Car* car;
};
int main()
{
const char* filename = "C:/xiaoyu/hh.txt";
FILE* fp = fopen(filename, "wb");
Car* car = (Car*)malloc(sizeof(Car));
strcpy(car->marker, "chevrolet");
car->price = 10;
Citizen who = { "shaofa",100 };
who.car = car;
//写
fwrite(&who.name, 1, 16, fp);
fwrite(&who.deposize, 1, 4, fp);
if (who.car!=NULL)
{
fwrite("Y", 1, 1, fp);//先写入一个标志符,Y/N
fwrite(&who.car->marker, 1, 32, fp);
fwrite(&who.car->price, 1, 4, fp);
}
else
{
fwrite("N", 1, 1, fp);
}
fclose(fp);
//读
FILE* fp1 = fopen(filename, "rb");
Citizen who1;
fread(&who1.name, 1, 16, fp1);
fread(&who1.deposize, 1, 4, fp1);
char has = 'N';
fread(&has, 1, 1, fp1);
if (has == 'Y')
{
Car* car = (Car*)malloc(sizeof(Car));
fread(&car->marker, 1, 32, fp1);
fread(&car->price, 1, 4, fp1);
who1.car = car;
}
else
{
who1.car = NULL;
}
fclose(fp1);
free(car);
return 0;
}
6、随机读取数据
借助于fseek函数,SEEK_SET表示开始位置,SEEK_END表示结束位置,SEEK_CUR表示当前位置。比如:
Car car;
fseek(fp, 79 * sizeof(Car), SEEK_SET);//读取第80个对象。0成功,-1失败
fread(&car, 1, sizeof(Car), fp);
但fseek坚决要杜绝使用,严重损坏物理设备。
方法:按文本方法存取数据,就是把所以的数据转换为字符串的形式进行存取
按行存取的实现方法:
存储方式一如下:
char ip[] = "192.168.1.100";
int port = 8080;
char line[256];
sprintf(line, "ip = %s \n", ip);
fwrite(line, 1,strlen(line), fp);
sprintf(line, "port = %d \n", port);
fwrite(line, 1,strlen(line), fp);
存储方式二,直接使用fprintf函数写入:
char ip[] = "192.168.1.100";
int port = 8080;
char line[256];
fprintf(fp, "ip = %s \n", ip);
fprintf(fp, "port = %d \n", port);
读取文件方式:
用fread函数的话,因为不知道有多少行,需要进行读取判断,确定是否读取到‘\n’,比较麻烦。
所以使用fgets函数,会自动检测换行符,读取到‘\n’时,停止读取,返回实际读取的字节长度。(sscanf函数只适合提取数字,不能解析字符串)
char buf[256];
while (!feof(fp))
{
char* line = fgets(buf, 256, fp); //buf缓存区
if (line)
{
printf("got:%s", line);
}
}
如果大家有问题,请在评论区留言讨论,如果喜欢小鱼写的文章,记得留下赞再走哦,试题来源afanihao官网,谢谢。