【C++ 存储和读取二进制文件以及类的实例】

很多时候程序运行时的数据都以类的对象的形式存储,那么如何将这些对象保存使得下一次运行程序的时候可以直接使用呢?

Step 1> 首先我们需要知道如何读写二进制文件:

inline size_t readBinaryFile(const char * filename,unsigned char* & data) 
{
    FILE* fp;
    fopen_s(&fp,filename, "rb");
    if (fp == NULL) return 0;  //空指针则返回0,文件打开失败
    fseek(fp, 0, SEEK_END);  //将文件指针移动至文件末尾
    size_t size = ftell(fp);  //计算文件大小,单位:Byte
    fseek(fp, 0, SEEK_SET); //把文件指针移回初始位置(文件开头)
    data = (unsigned char *)malloc(sizeof(unsigned char)*size);
    fread(data,size,1,fp);
    fclose(fp);
    return size;
}


//size:要写入的数据大小(单位:字节)
inline size_t writeBinaryFile(const char* filename, const unsigned char* data, size_t size)  
{
    FILE* fp;
    fopen_s(&fp,filename, "wb");
    if (fp == NULL) return 0;
    size_t written_size= fwrite(data, size, 1 ,fp);
    fclose(fp);
    return written_size;
}

注意这里readBinaryFile函数参数中的data指针必须得用引用,或者使用指针的指针,这是因为在函数内对指针重新分配了内存,如果只传指针,那么经过值传递之后形参实际上是实参的拷贝,对形参重新分配内存并不会改变实参(且指向的地址不再是实参的值了),写入的数据在函数外也无法访问。

Step 2 > 我们通过函数模板,将传入的任意类对象转成字节数组写入或者读取二进制文件即可

template<typename OB>
inline void saveObject(const char*filename,OB & object) //传入要保存的对象引用
{
    std::ofstream osm(filename, ios::out | ios::binary);
    osm.write((const char *)&object,sizeof(OB));
    osm.close();
}

template<typename OB>
inline void readObject(const char* filename, OB * object) //传入读取之后对象存储的指针
{
    std::ifstream ism(filename, ios::in | ios::binary);
    ism.read((char*)object, sizeof(OB));
    ism.close();
}

这里我们没有重新分配对象指针,因此可以不用写引用

以上使用到的头文件:
<stdio.h> - fopen_s函数和FILE类型
< fstream > - ifstream , ofstream
<stdlib.h> - malloc函数

References

  1. https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/fopen-s-wfopen-s?view=msvc-160
  2. http://www.cplusplus.com/reference/cstdlib/malloc/?kw=malloc
  3. http://www.cplusplus.com/reference/istream/istream/
  4. http://www.cplusplus.com/reference/fstream/ofstream/
  5. https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/fseek-fseeki64?view=msvc-160
  6. https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/ftell-ftelli64?view=msvc-160


原文链接:https://blog.csdn.net/qq_42885747/article/details/111845680

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
好的,你的问题是如何使用 File 的 readfile 函数来读取文件中的成绩并计算平均值输出到屏幕上。 首先,我们需要在 File 中定义一个 readfile 函数,该函数接受一个文件名作为参数,并返回读取到的成绩数据。该函数应该可以读取文本文件二进制文件。 接下来,在 File 中定义一个成员函数用于计算成绩平均值。该成员函数应该接受成绩数据作为参数,并返回平均值。 最后,在 File 中定义一个成员函数用于输出平均值到屏幕上。该成员函数应该接受平均值作为参数,并将其输出到屏幕上。 以下是一个基本的 File 的示例代码: ```c++ #include <iostream> #include <fstream> #include <vector> class File { public: std::vector<int> readfile(std::string filename) { std::vector<int> scores; std::ifstream infile; infile.open(filename, std::ios::binary); if (infile.fail()) { infile.open(filename); if (infile.fail()) { std::cerr << "Unable to open file!" << std::endl; exit(1); } } int score; while (infile.read(reinterpret_cast<char*>(&score), sizeof(score))) { scores.push_back(score); } infile.close(); return scores; } double calculateAverage(std::vector<int> scores) { double sum = 0; for (int i = 0; i < scores.size(); i++) { sum += scores[i]; } return sum / scores.size(); } void printAverage(double average) { std::cout << "Average score: " << average << std::endl; } }; int main() { File file; std::vector<int> scores = file.readfile("1.txt"); double average = file.calculateAverage(scores); file.printAverage(average); return 0; } ``` 该示例代码中,我们使用了 vector 容器来存储读取到的成绩数据。readfile 函数使用 ifstream 读取文件中的成绩数据,并将其存储到 scores 容器中。calculateAverage 函数接受 scores 容器作为参数,并计算平均值。printAverage 函数接受平均值作为参数,并将其输出到屏幕上。 在 main 函数中,我们实例化了一个 File 对象,并调用其成员函数来完成读取文件、计算平均值和输出平均值的工作。由于 readfile 函数可以读取文本文件二进制文件,所以我们可以将文件名 "1.txt" 或 "1.dat" 传递给 readfile 函数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值