MFC 二进制文件数据管理

我要采集大约0-100条曲线数据,每采集一条在列表上显示出来,方便查询删除等管理,请问所采集的曲线如果用 fstream 二进制方式存储的话,能否存储在一个文件里?每条曲线坐标点数在500到1000个坐标点的样子,长短不一要如何读写呢?如果不能存到一个二进制文件里,那就是一条曲线 一个文件 那如何管理这些二进制文件呢?

引用new bing作答:
三个问题的回答分别如下:
1 可以将所有的曲线数据存储到同一个二进制文件中,只需要在文件中规定好每条曲线的数据格式和长度,以便读取时能够准确地分离出每条曲线的数据。
以下是一个简单的示例代码来演示如何存储和读取二进制文件中的多条曲线数据。

存储多条曲线数据到同一个二进制文件中:

#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

struct Point {
    float x;
    float y;
};

struct Curve {
    vector<Point> points;
};

void WriteCurvesToFile(const vector<Curve>& curves, const char* filename) {
    ofstream out(filename, ios::binary);
    if (out) {
        // 写入曲线数量
        int num_curves = curves.size();
        out.write(reinterpret_cast<char*>(&num_curves), sizeof(int));

        // 写入每条曲线的数据
        for (const auto& curve : curves) {
            // 写入曲线长度
            int num_points = curve.points.size();
            out.write(reinterpret_cast<char*>(&num_points), sizeof(int));

            // 写入曲线数据
            out.write(reinterpret_cast<char*>(curve.points.data()), sizeof(Point) * num_points);
        }

        out.close();
    }
}

int main() {
    vector<Curve> curves = {
        {{ {0, 0}, {1, 1}, {2, 4} }},
        {{ {0, 0}, {1, 2}, {2, 6} }},
        {{ {0, 0}, {1, 3}, {2, 9} }}
    };

    WriteCurvesToFile(curves, "curves.bin");

    return 0;
}

2 对于不同长度的曲线数据,可以采用同一种数据格式进行存储,例如在文件中先存储曲线的总点数,再依次存储每个点的 x 坐标和 y 坐标,这样读取时可以先读取总点数,再根据总点数读取每个点的坐标信息。
读取同一个二进制文件中的多条曲线数据:

#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

struct Point {
    float x;
    float y;
};

struct Curve {
    vector<Point> points;
};

vector<Curve> ReadCurvesFromFile(const char* filename) {
    vector<Curve> curves;

    ifstream in(filename, ios::binary);
    if (in) {
        // 读取曲线数量
        int num_curves = 0;
        in.read(reinterpret_cast<char*>(&num_curves), sizeof(int));

        // 读取每条曲线的数据
        for (int i = 0; i < num_curves; i++) {
            Curve curve;

            // 读取曲线长度
            int num_points = 0;
            in.read(reinterpret_cast<char*>(&num_points), sizeof(int));

            // 读取曲线数据
            for (int j = 0; j < num_points; j++) {
                Point p;
                in.read(reinterpret_cast<char*>(&p), sizeof(Point));
                curve.points.push_back(p);
            }

            curves.push_back(curve);
        }

        in.close();
    }

    return curves;
}

int main() {
    vector<Curve> curves = ReadCurvesFromFile("curves.bin");

    // 输出读取到的曲线数据
    for (const auto& curve : curves) {
        for (const auto& point : curve.points) {
            cout << "(" << point.x << ", " << point.y << ") ";
        }
        cout << endl;
    }

    return 0;
}

3 如果每条曲线存储到一个文件中,可以采用文件名与曲线编号对应的方式来管理这些二进制文件,例如第一条曲线对应的文件名为"curve_1.bin",第二条曲线对应的文件名为"curve_2.bin",以此类推。这样可以方便地进行查询和删除操作。另外,为了避免过多的文件占用系统资源,可以考虑定期清理一些不再需要的曲线文件。
存储每条曲线数据到一个单独的二进制文件中:

#include <iostream>
#include <fstream>
#include <vector>
#include <sstream>

using namespace std;

struct Point {
    float x;
    float y;
};

struct Curve {
    vector<Point> points;
};

void WriteCurveToFile(const Curve& curve, const char* filename) {
    ofstream out(filename, ios::binary);
    if (out) {
        // 写入曲线长度
        int num_points = curve.points.size();
        out.write(reinterpret_cast<char*>(&num_points), sizeof(int));

        // 写入曲线数据
        out.write(reinterpret_cast<char*>(curve.points.data()), sizeof(Point) * num_points);

        out.close();
    }
}

Curve ReadCurveFromFile(const char* filename) {
    Curve curve;

    ifstream in(filename, ios::binary);
    if (in) {
        // 读取曲线长度
        int num_points = 0;
        in.read(reinterpret_cast<char*>(&num_points), sizeof(int));

        // 读取曲线数据
        for (int j = 0; j < num_points; j++) {
            Point p;
            in.read(reinterpret_cast<char*>(&p), sizeof(Point));
            curve.points.push_back(p);
        }

        in.close();
    }

    return curve;
}

string GetCurveFilename(int index) {
    stringstream ss;
    ss << "curve_" << index << ".bin";
    return ss.str();
}

int main() {
    vector<Curve> curves = {
        {{ {0, 0}, {1, 1}, {2, 4} }},
        {{ {0, 0}, {1, 2}, {2, 6} }},
        {{ {0, 0}, {1, 3}, {2, 9} }}
    };

    // 存储每条曲线到单独的文件中
    for (int i = 0; i < curves.size(); i++) {
        WriteCurveToFile(curves[i], GetCurveFilename(i).c_str());
    }

    // 读取每条曲线文件并输出数据
    for (int i = 0; i < curves.size(); i++) {
        Curve curve = ReadCurveFromFile(GetCurveFilename(i).c_str());

        // 输出读取到的曲线数据
        for (const auto& point : curve.points) {
            cout << "(" << point.x << ", " << point.y << ") ";
        }
        cout << endl;
    }

    return 0;
}

在这个示例代码中,我们定义了两个函数 WriteCurveToFile 和 ReadCurveFromFile,用于将一条曲线数据存储到单独的二进制文件中,以及从二进制文件中读取一条曲线数据。我们还定义了一个函数 GetCurveFilename,用于生成每条曲线的文件名。

在主函数中,我们先将每条曲线数据存储到单独的二进制文件中,然后读取每条曲线文件并输出数据。

该回答引用chatgpt:
是可以将多个曲线数据存储到一个二进制文件中的。你可以定义一个数据结构来存储每个曲线的坐标点数据和相关信息,然后使用 fstream 以二进制模式将这些数据写入文件中。在读取数据时,你可以先读取每条曲线的信息,然后根据每条曲线的坐标点数读取相应的坐标数据。

对于曲线数据长度不一的情况,你可以在每个曲线信息中添加一个字段来记录该曲线的坐标点数,这样在读取数据时就可以根据该字段读取相应长度的数据。

如果你需要对存储的曲线数据进行查询和删除等管理操作,你可以在每个曲线信息中添加一个唯一标识符,然后将所有曲线数据的信息存储到一个索引文件中,用于快速查询和管理。当需要删除某个曲线时,可以将该曲线的信息从索引文件中删除,并将其对应的二进制文件删除。

如果你觉得将每个曲线存储到一个二进制文件中更为方便,也可以采用类似的方式进行管理,即为每个二进制文件添加一个唯一标识符,并将所有二进制文件的信息存储到一个索引文件中进行管理

基于ChatGPT的回答:
可以将所有曲线数据存储在一个二进制文件中,每条曲线之间用特定的标识符分隔开来,比如可以在每条曲线前加上一个特定的字符串,如"CurveData",表示这是一条曲线的开始,然后记录曲线数据,最后再加上一个特定的字符串,如"EndCurve",表示这条曲线的结束。这样可以通过读取文件时识别出每条曲线的起始和结束位置,从而进行读取和管理。

读写时可以使用fstream库中的二进制读写函数,如write和read函数,对于长度不一的曲线,可以在文件中先记录每条曲线的长度信息,读取时先读取曲线长度,再读取对应长度的坐标数据。对于管理二进制文件,可以使用文件夹来存储每条曲线的二进制文件,可以根据需要进行查询、删除等操作。

  1. 可以存在一个文件里,文件开头预留几K保存int数组,表示每一条曲线数据的文件偏移位置

  2. 写的时候文件开头写入偏移位置,曲线数据按顺序一个一个写入即可,读的时候按偏移位置+下一个偏移位置就能读到数据位置和长度

  3. 一个曲线一个文件可以直接用数字作文件名,并保存当前最新数字到一个文件,每保存一条曲线,这个数字+1并保存

可以将所有曲线数据存储在一个二进制文件中,每个曲线之间使用特殊分隔符分割。例如可以使用两个连续的整数 0x7E7E 来标记每条曲线的开始和结束位置。

读取时,先读取两个连续的整数,判断是否为分隔符。如果是,则认为已经读取完一条曲线数据,需要进行处理,否则按照该曲线的长度读取对应长度的数据作为一条曲线数据,再按照相同的方式读取下一条曲线数据。

如果不能存储在一个二进制文件中,则可以为每条曲线创建一个单独的二进制文件。可以以曲线名或编号作为文件名,并将这些文件存储在一个目录中。可以通过遍历该目录来获取所有的曲线文件,并按照需要对其进行读取、删除或修改操作。
下面是一个示例代码,演示如何将多条曲线数据存储在同一个二进制文件中,并使用分隔符进行区分。同时也包含一个单独的曲线数据保存为二进制文件和读取的示例。

#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

// 分隔符
const int DELIMITER = 0x7E7E;

struct Point {
    float x;
    float y;
};

struct CurveData {
    vector<Point> points;
};

// 将一个曲线数据写入到文件
void writeCurveToFile(const string& filename, const CurveData& curve) {
    ofstream fout(filename.c_str(), ios::binary);
    if (fout.is_open()) {
        for (int i = 0; i < curve.points.size(); i++) {
            fout.write((char*)&curve.points[i].x, sizeof(float));
            fout.write((char*)&curve.points[i].y, sizeof(float));
        }
        fout.close();
    } else {
        cerr << "Failed to open file: " << filename << endl;
    }
}

// 从文件读取一个曲线数据
CurveData readCurveFromFile(const string& filename) {
    CurveData curve;
    ifstream fin(filename.c_str(), ios::binary);
    if (fin.is_open()) {
        Point p;
        while (fin.read((char*)&p.x, sizeof(float))) {
            fin.read((char*)&p.y, sizeof(float));
            curve.points.push_back(p);
        }
        fin.close();
    } else {
        cerr << "Failed to open file: " << filename << endl;
    }
    return curve;
}

// 将多条曲线数据写入到同一个文件中
void writeCurvesToFile(const string& filename, const vector<CurveData>& curves) {
    ofstream fout(filename.c_str(), ios::binary);
    if (fout.is_open()) {
        for (int i = 0; i < curves.size(); i++) {
            // 写入分隔符
            fout.write((char*)&DELIMITER, sizeof(int));
            // 写入曲线长度
            int size = curves[i].points.size();
            fout.write((char*)&size, sizeof(int));
            // 写入曲线数据
            for (int j = 0; j < curves[i].points.size(); j++) {
                fout.write((char*)&curves[i].points[j].x, sizeof(float));
                fout.write((char*)&curves[i].points[j].y, sizeof(float));
            }
        }
        fout.close();
    } else {
        cerr << "Failed to open file: " << filename << endl;
    }
}

// 从文件读取多条曲线数据
vector<CurveData> readCurvesFromFile(const string& filename) {
    vector<CurveData> curves;
    ifstream fin(filename.c_str(), ios::binary);
    if (fin.is_open()) {
        while (!fin.eof()) {
            int delimiter;
            fin.read((char*)&delimiter, sizeof(int)); // 读取分隔符
            if (delimiter == DELIMITER) {
                int size;
                fin.read((char*)&size, sizeof(int)); // 读取曲线长度
                CurveData curve;
                for (int i = 0; i < size; i++) {
                    Point p;
                    fin.read((char*)&p.x, sizeof(float));
                    fin.read((char*)&p.y, sizeof(float));
                    curve.points.push_back(p);
                }
                curves.push_back(curve);
            }
        }
        fin.close();
    } else {
        cerr << "Failed to open file: " << filename << endl;
    }
    return curves;
}

int main() {
    // 生成示例曲线数据
    CurveData curve1, curve2;
    for (int i = 0; i < 1000; i++) {
        Point p;
        p.x = i * 0.1f;
        p.y = sin(p.x);
        curve1.points.push_back(p);
    }
    for (int i = 0; i < 500; i++) {
        Point p;
        p.x = i * 0.2f;
        p.y = cos(p.x);
        curve2.points.push_back(p);
    }

    // 将多条曲线数据写入文件
    vector<CurveData> curves;
    curves.push_back(curve1);
    curves.push_back(curve2);
    writeCurvesToFile("curves.bin", curves);

    // 从文件读取多条曲线数据
    vector<CurveData> readCurves = readCurvesFromFile("curves.bin");
    for (int i = 0; i < readCurves.size(); i++) {
        cout << "Curve " << i << ": " << readCurves[i].points.size() << " points" << endl;
    }

    // 将单条曲线数据写入文件
    writeCurveToFile("curve1.bin", curve1);

    // 从文件读取单条曲线数据
    CurveData readCurve = readCurveFromFile("curve1.bin");
    cout << "Curve 1: " << readCurve.points.size() << " points" << endl;

    return 0;
}

在这个示例中,我们首先定义了一个 Point 结构体来表示二维坐标点,以及一个 CurveData 结构体来存储曲线数据。接着,我们提供了一个 writeCurveToFile 函数和一个 readCurveFromFile 函数,用于将单条曲线数据写入到二进制文件中和从二进制文件中读取单条曲线数据。

对于多条曲线数据的存储和读取,我们使用了 writeCurvesToFile 函数和 readCurvesFromFile 函数。在写数据时,我们首先写入一个分隔符,然后写入该曲线的长度,最后写入所有坐标点。读数据时,我们先读取一个整数作为分隔符,如果是分隔符则读取下一个整数作为曲线长度,最后读取所有坐标点。

您可以使用 fstream 的二进制方式将多条曲线数据存储在同一个文件中。二进制文件存储的数据是按字节顺序存储的,因此您可以将每条曲线的数据结构作为一个整体写入文件,并通过记录每条曲线的起始位置和长度来方便地读取和管理数据。

以下是一个简单的示例,演示如何使用 fstream 和结构体来存储多条曲线数据:

#include <fstream>
#include <vector>

struct CurveData
{
    int id;
    std::vector<double> data;
};

int main()
{
    std::vector<CurveData> curves = { { 1, { 1.0, 2.0, 3.0 } }, { 2, { 4.0, 5.0, 6.0 } }, { 3, { 7.0, 8.0, 9.0 } } };

    std::ofstream file("curves.bin", std::ios::binary);

    // 写入曲线数据
    for (auto& curve : curves)
    {
        // 记录起始位置和长度
        int startPos = file.tellp();
        int size = sizeof(curve.id) + curve.data.size() * sizeof(double);

        // 写入数据
        file.write(reinterpret_cast<const char*>(&curve.id), sizeof(curve.id));
        file.write(reinterpret_cast<const char*>(curve.data.data()), curve.data.size() * sizeof(double));

        // 记录起始位置和长度
        int endPos = file.tellp();

        // 回到起始位置,写入位置和长度信息
        file.seekp(startPos);
        file.write(reinterpret_cast<const char*>(&startPos), sizeof(startPos));
        file.write(reinterpret_cast<const char*>(&size), sizeof(size));

        // 回到文件结尾
        file.seekp(endPos);
    }

    file.close();

    // 读取曲线数据
    std::ifstream infile("curves.bin", std::ios::binary);

    // 计算文件大小
    infile.seekg(0, std::ios::end);
    int fileSize = infile.tellg();
    infile.seekg(0);

    while (infile.tellg() < fileSize)
    {
        // 读取位置和长度信息
        int startPos;
        int size;
        infile.read(reinterpret_cast<char*>(&startPos), sizeof(startPos));
        infile.read(reinterpret_cast<char*>(&size), sizeof(size));

        // 读取曲线数据
        CurveData curve;
        curve.id = 0;
        curve.data.resize((size - sizeof(curve.id)) / sizeof(double));
        infile.read(reinterpret_cast<char*>(&curve.id), sizeof(curve.id));
        infile.read(reinterpret_cast<char*>(curve.data.data()), curve.data.size() * sizeof(double));

        // 显示曲线数据
        std::cout << "Curve " << curve.id << ": ";
        for (auto& value : curve.data)
        {
            std::cout << value << " ";
        }
        std::cout << std::endl;

        // 移动文件指针
        infile.seekg(startPos + size);
    }

    infile.close();

    return 0;
}


在上面的示例中,我们首先定义了一个 CurveData 结构体,用于存储每条曲线的数据。然后,我们创建一个 vector,其中包含三条曲线数据,并使用 fstream 的二进制方式将这些数据写入一个名为 curves.bin 的文件中。在写入每条曲线数据时,我们首先记录了数据的起始位置和长度,然后写入曲线 id 和数据向量中的每个元素。最后,我们回到数据起始位置,并将位置和长度信息写入文件,然后继续写入下一条曲线数据。

在读取数据时,我们首先计算文件大小,然后循环读取每条曲线的数据。对于每条曲线,我们首先读取起始位置和长度信息,然后根据长度计算曲线数据的大小,并读取曲线 id 和数据向量中的每个元素。最后,我们移动文件指针到下一条曲线数据的起始位置。

在读取数据时,我们使用了 tellg 函数和 seekg 函数来移动文件指针。这些函数可以帮助我们定位和移动文件指针,以便读取和写入正确的数据。注意,当我们使用 tellg 函数和 seekg 函数时,需要指定 ios::binary 标志,以确保文件指针按字节顺序移动。

总之,使用 fstream 的二进制方式存储曲线数据可以让您将多条曲线数据存储在同一个文件中,并通过记录位置和长度信息来方便地管理和读取数据。但是,需要注意文件指针的移动和字节顺序等问题,以确保数据的正确读取和写入。

如果每条曲线的坐标点数不同,那么您可以在写入数据时,先写入每条曲线数据的长度信息,这样在读取数据时,就可以根据长度信息读取每条曲线的数据,而不需要提前知道每条曲线的坐标点数。

具体地,您可以在写入每条曲线数据之前,先将曲线数据的长度信息写入文件,例如使用下面的代码:

// 写入曲线数据长度
size_t data_length = curve_data.size();
output_file.write(reinterpret_cast<const char*>(&data_length), sizeof(size_t));

// 写入曲线 id
output_file.write(reinterpret_cast<const char*>(&curve_id), sizeof(int));

// 写入曲线数据
output_file.write(reinterpret_cast<const char*>(&curve_data[0]), data_length * sizeof(double));


在读取数据时,您可以先读取每条曲线数据的长度信息,然后根据长度信息读取每条曲线的数据,例如使用下面的代码:

// 读取曲线数据长度
size_t data_length;
input_file.read(reinterpret_cast<char*>(&data_length), sizeof(size_t));

// 读取曲线 id
int curve_id;
input_file.read(reinterpret_cast<char*>(&curve_id), sizeof(int));

// 读取曲线数据
std::vector<double> curve_data(data_length);
input_file.read(reinterpret_cast<char*>(&curve_data[0]), data_length * sizeof(double));



这样,即使每条曲线的坐标点数不同,也可以方便地读写数据。当然,在实际应用中,您可能还需要考虑如何管理和查询这些数据,例如使用一个数据结构来存储曲线数据和它们的长度信息,并提供查询和删除等接口。
以下是一个可能的实现示例,它使用一个名为 CurveData 的类来管理曲线数据和长度信息:


```c++




#include <fstream>
#include <iostream>
#include <vector>

class CurveData {
public:
    CurveData(int id, const std::vector<double>& data)
        : id_(id), data_(data)
    {
        length_ = data_.size();
    }

    int GetId() const {
        return id_;
    }

    const std::vector<double>& GetData() const {
        return data_;
    }

    size_t GetLength() const {
        return length_;
    }

private:
    int id_;
    std::vector<double> data_;
    size_t length_;
};

class CurveDataFile {
public:
    CurveDataFile(const std::string& filename)
        : filename_(filename)
    {
    }

    void AddCurve(const CurveData& curve) {
        std::ofstream output_file(filename_, std::ios::app | std::ios::binary);
        if (!output_file.is_open()) {
            std::cerr << "Failed to open file " << filename_ << std::endl;
            return;
        }

        size_t data_length = curve.GetLength();
        output_file.write(reinterpret_cast<const char*>(&data_length), sizeof(size_t));

        int curve_id = curve.GetId();
        output_file.write(reinterpret_cast<const char*>(&curve_id), sizeof(int));

        const std::vector<double>& curve_data = curve.GetData();
        output_file.write(reinterpret_cast<const char*>(&curve_data[0]), data_length * sizeof(double));

        output_file.close();
    }

    std::vector<CurveData> GetCurves() const {
        std::vector<CurveData> curves;

        std::ifstream input_file(filename_, std::ios::binary);
        if (!input_file.is_open()) {
            std::cerr << "Failed to open file " << filename_ << std::endl;
            return curves;
        }

        input_file.seekg(0, std::ios::end);
        size_t file_size = input_file.tellg();
        input_file.seekg(0, std::ios::beg);

        while (input_file.tellg() < file_size) {
            size_t data_length;
            input_file.read(reinterpret_cast<char*>(&data_length), sizeof(size_t));

            int curve_id;
            input_file.read(reinterpret_cast<char*>(&curve_id), sizeof(int));

            std::vector<double> curve_data(data_length);
            input_file.read(reinterpret_cast<char*>(&curve_data[0]), data_length * sizeof(double));

            curves.emplace_back(curve_id, curve_data);
        }

        input_file.close();

        return curves;
    }

    bool DeleteCurve(int id) {
        std::vector<CurveData> curves = GetCurves();

        bool found = false;
        std::ofstream output_file(filename_, std::ios::trunc | std::ios::binary);
        for (const CurveData& curve : curves) {
            if (curve.GetId() == id) {
                found = true;
            } else {
                size_t data_length = curve.GetLength();
                output_file.write(reinterpret_cast<const char*>(&data_length), sizeof(size_t));

                int curve_id = curve.GetId();
                output_file.write(reinterpret_cast<const char*>(&curve_id), sizeof(int));

                const std::vector<double>& curve_data = curve.GetData();
                output_file.write(reinterpret_cast<const char*>(&curve_data[0]), data_length * sizeof(double));
            }
        }

        output_file.close();

        return found;
    }

private:
    std::string filename_;
};


在这个实现中,CurveData 类封装了每条曲线的 id、数据和长度信息,CurveDataFile 类封装了对数据文件的读写操作。AddCurve 方法将新的曲线数据写入文件,而 GetCurves 方法从文件中读取所有曲线数据。DeleteCurve 方法可以从文件中删除具有特定 id 的曲线数据。在 AddCurve 方法中,我们使用 std::ios::app 标志打开文件以进行追加,而在 DeleteCurve 方法中,我们使用 std::ios::trunc 标志重新打开文件以覆盖其内容。

对于每条曲线,我们首先将数据长度写入文件(使用 sizeof(size_t)),然后写入曲线 id(使用 sizeof(int))。最后,我们将实际数据写入文件(使用 sizeof(double))。

对于读取操作,我们首先使用 std::ios::binary 标志打开文件以进行二进制读取。我们首先获取文件大小,然后在文件中循环,每次读取一个曲线的长度、id 和实际数据。最后,我们将曲线数据封装在 CurveData 对象中,并将其添加到 curves 向量中。
这只是一个简单的示例实现,并且可能需要进行修改以满足特定需求。例如,您可能需要添加更多错误检查来确保读写操作的正确性。

以下内容部分参考ChatGPT模型:


可以将每条曲线的数据存储在一个结构体中,然后将所有结构体存储在同一个文件中。具体步骤如下:

  1. 定义存储曲线数据的结构体,包括曲线编号、坐标点数和坐标数组。
struct CurveData {
    int curveId;         // 曲线编号
    int pointCount;      // 坐标点数
    double *points;      // 坐标数组
};
  1. 采集一条曲线后,将曲线数据存储在一个结构体中,并将结构体写入文件中。
CurveData data;
data.curveId = curveId;       // 设置曲线编号
data.pointCount = pointCount; // 设置坐标点数
data.points = new double[pointCount];  // 申请坐标数组内存
memcpy(data.points, points, pointCount * sizeof(double)); // 复制坐标数据

ofstream outFile("curve.dat", ios::binary | ios::app); // 打开文件,以二进制追加方式写入
outFile.write((char*)&data, sizeof(CurveData)); // 写入结构体数据
outFile.close(); // 关闭文件

delete[] data.points; // 释放坐标数组内存
  1. 读取文件中的所有结构体数据,并将其存储在一个动态数组中。
vector<CurveData> curves; // 存储所有曲线数据的动态数组

ifstream inFile("curve.dat", ios::binary); // 打开文件,以二进制方式读取
CurveData data;
while (inFile.read((char*)&data, sizeof(CurveData))) { // 读取结构体数据
    curves.push_back(data); // 将结构体数据存储在动态数组中
}
inFile.close(); // 关闭文件
  1. 在列表上显示曲线数据时,可以遍历动态数组,并将每条曲线的编号、坐标点数和坐标数组显示出来。
for (int i = 0; i < curves.size(); i++) {
    CurveData data = curves[i];
    cout << "Curve " << data.curveId << ": " << data.pointCount << " points" << endl;
    for (int j = 0; j < data.pointCount; j++) {
        cout << "(" << data.points[j*2] << ", " << data.points[j*2+1] << ") ";
    }
    cout << endl;
}
  1. 删除一条曲线时,可以遍历动态数组,找到对应的曲线数据,并将其从数组中删除。然后重新打开文件,以二进制写入方式将剩余曲线数据写入文件中。
int curveIdToDelete = 3; // 要删除的曲线编号
for (vector<CurveData>::iterator it = curves.begin(); it != curves.end(); ++it) {
    if (it->curveId == curveIdToDelete) {
        curves.erase(it); // 从动态数组中删除对应的曲线数据
        break;
    }
}

ofstream outFile("curve.dat", ios::binary); // 打开文件,以二进制写入方式写入
for (int i = 0; i < curves.size(); i++) {
    CurveData data = curves[i];
    outFile.write((char*)&data, sizeof(CurveData)); // 写入剩余曲线数据
}
outFile.close(); // 关闭文件

如果我的建议对您有帮助、请点击采纳、祝您生活愉快

该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
可以使用 fstream 二进制方式将多条曲线数据存储在一个文件中。可以按照以下步骤进行:

1、 定义数据结构:为了方便存储和读取,可以定义一个结构体来存储每条曲线的信息,包括曲线的名称、坐标点数和坐标点数据。

typedef struct {
    std::string name; // 曲线名称
    int num_points; // 坐标点数
    std::vector<double> x; // x 坐标点数据
    std::vector<double> y; // y 坐标点数据
} CurveData;

2、 存储数据:将每条曲线的数据存储到一个 vector 中,然后将整个 vector 存储到一个二进制文件中。

std::vector<CurveData> curves; // 存储所有曲线数据的 vector

// 添加一条曲线数据到 vector 中
CurveData curve;
curve.name = "Curve 1";
curve.num_points = 1000;
curve.x.resize(curve.num_points);
curve.y.resize(curve.num_points);
// 填充 x 和 y 数据
curves.push_back(curve);

// 将所有曲线数据存储到二进制文件中
std::ofstream out("data.bin", std::ios::binary);
int num_curves = curves.size();
out.write((char*)&num_curves, sizeof(int));
for (int i = 0; i < num_curves; i++) {
    CurveData& curve = curves[i];
    int name_len = curve.name.length();
    out.write((char*)&name_len, sizeof(int));
    out.write(curve.name.c_str(), name_len);
    out.write((char*)&curve.num_points, sizeof(int));
    out.write((char*)&curve.x[0], sizeof(double) * curve.num_points);
    out.write((char*)&curve.y[0], sizeof(double) * curve.num_points);
}
out.close();

3、 读取数据:从二进制文件中读取数据时,先读取曲线数目,然后循环读取每条曲线的信息。

std::vector<CurveData> curves; // 存储所有曲线数据的 vector

// 从二进制文件中读取所有曲线数据
std::ifstream in("data.bin", std::ios::binary);
int num_curves;
in.read((char*)&num_curves, sizeof(int));
for (int i = 0; i < num_curves; i++) {
    CurveData curve;
    int name_len;
    in.read((char*)&name_len, sizeof(int));
    char* name_buf = new char[name_len + 1];
    in.read(name_buf, name_len);
    name_buf[name_len] = '\0';
    curve.name = name_buf;
    delete[] name_buf;
    in.read((char*)&curve.num_points, sizeof(int));
    curve.x.resize(curve.num_points);
    curve.y.resize(curve.num_points);
    in.read((char*)&curve.x[0], sizeof(double) * curve.num_points);
    in.read((char*)&curve.y[0], sizeof(double) * curve.num_points);
    curves.push_back(curve);
}
in.close();

如果不能将多条曲线数据存储在一个文件中,那么可以将每条曲线存储到一个二进制文件中,文件名可以用曲线名称来命名。然后可以使用一个列表来管理所有的二进制文件名,方便查询、删除等操作。


如果以上回答对您有所帮助,点击一下采纳该答案~谢谢

mfc存储颜色到mysql_mfc存储二进制文件
可以借鉴下
https://blog.csdn.net/weixin_34670892/article/details/113690543

引用chatGPT作答,根据您的需求,可以将每条曲线的数据以二进制形式存储在同一个文件中,可以使用fstream库中的二进制文件读写操作来实现。

您可以使用ofstream类来创建二进制文件并将每条曲线的数据写入文件中。当您需要读取曲线数据时,可以使用ifstream类打开二进制文件并按照存储的格式读取数据。

对于每条曲线,您需要存储曲线的标识(例如名称或编号)以及曲线的坐标点数和坐标值。可以将曲线标识和坐标点数作为文件头信息存储在文件中,并且在读取数据时首先读取文件头信息以确定曲线的标识和坐标点数,然后再读取实际的坐标数据。

对于不同长度的曲线,您可以在存储数据时将每条曲线的坐标点数一起存储,这样在读取数据时就可以动态地分配内存来存储每条曲线的数据。另外,您还可以使用vector等STL容器来动态存储每条曲线的数据,这样可以方便地进行查询、删除等管理操作。

下面是一个简单的代码示例,用于将曲线数据以二进制形式存储在同一个文件中:

#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

struct CurveData {
    string name;
    int numPoints;
    vector<double> points;
};

void writeCurveData(ofstream& outfile, const CurveData& curve) {
    // 先写入曲线名称和坐标点数
    outfile.write(curve.name.c_str(), curve.name.length() + 1);
    outfile.write(reinterpret_cast<const char*>(&curve.numPoints), sizeof(curve.numPoints));

    // 再写入每个坐标点的数据
    for (const auto& point : curve.points) {
        outfile.write(reinterpret_cast<const char*>(&point), sizeof(point));
    }
}

CurveData readCurveData(ifstream& infile) {
    CurveData curve;
    char nameBuffer[256];
    infile.read(nameBuffer, 256);
    curve.name = nameBuffer;

    infile.read(reinterpret_cast<char*>(&curve.numPoints), sizeof(curve.numPoints));

    curve.points.resize(curve.numPoints * 2);
    for (auto& point : curve.points) {
        infile.read(reinterpret_cast<char*>(&point), sizeof(point));
    }

    return curve;
}

int main() {
    vector<CurveData> curves;

    // 添加曲线数据到curves中...

    ofstream file("curves.dat", ios::binary);
    if (file.is_open()) {
        // 依次将每条曲线的数据写入文件
        for (const auto& curve : curves) {
            writeCurveData(file, curve);
        }
        file.close();
    } else {
        cerr << "无法创建文件!" << endl;
        return -1;
    }

    ifstream infile("curves.dat", ios::binary);
    if (infile.is_open()) {
        // 读取每条曲线的数据并输出到控制台
        while (infile.peek() != EOF) {
            auto curve = readCurveData(infile);

            cout << "曲线名称:" << curve.name << endl;
            cout << "坐标点数:" << curve.numPoints << endl;
            cout << "坐标数据:";
            for (int i = 0; i < curve.numPoints; i++) {
                cout << "(" << curve.points[i*2] << "," << curve.points[i*2+1] << ") ";
            }
            cout << endl;
        }
        infile.close();
    } else {
        cerr << "无法打开文件!" << endl;
        return -1;
    }

    return 0;
}

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
答案:

可以使用 fstream 二进制方式将多条曲线数据存储在一个文件中。可以将每条曲线的点数存储在前面,以便于读取数据。读写的时候可以根据点数进行分段读写。

假设每个坐标点的数据类型是 double,可以采用以下方式来存储曲线数据:

#include <fstream>
#include <vector>

using namespace std;

void write_data(const char* filename, const vector<vector<double>>& data) {
    ofstream ofs(filename, ios::binary);
    int count = data.size();
    ofs.write(reinterpret_cast<char*>(&count), sizeof(count)); // 写入曲线数目
    for (const auto& curve : data) {
        int n = curve.size();
        ofs.write(reinterpret_cast<char*>(&n), sizeof(n)); // 写入点数
        ofs.write(reinterpret_cast<const char*>(curve.data()), sizeof(double) * n); // 写入坐标数据
    }
}

vector<vector<double>> read_data(const char* filename) {
    ifstream ifs(filename, ios::binary);
    int count;
    ifs.read(reinterpret_cast<char*>(&count), sizeof(count)); // 读取曲线数目
    vector<vector<double>> data(count);
    for (auto& curve : data) {
        int n;
        ifs.read(reinterpret_cast<char*>(&n), sizeof(n)); // 读取点数
        curve.resize(n);
        ifs.read(reinterpret_cast<char*>(curve.data()), sizeof(double) * n); // 读取坐标数据
    }
    return data;
}

上述代码中, write_data 函数通过 ofstream 来写入曲线数据, read_data 函数通过 ifstream 来读取曲线数据。可以将需要保存的曲线数据放到一个 vector<vector<double>> 中传给 write_data 函数进行保存,从文件中读取曲线数据的时候则需要调用 read_data 函数。
如果我的回答解决了您的问题,请采纳!