C/C++试题集——文件篇

主要:数据存储(原则:保证能写入,也能读出并还原)

方法:按字节存储
首先都是读取路径,并正确打开
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官网,谢谢。

猜你喜欢

转载自blog.csdn.net/zllljf/article/details/80510414