将数组写入二进制文件?

ert*_*ion 5 c file-io

我需要一些帮助 - 下一段代码将一个长的双动态数组写入文件

int nx = 10, ny = 10;
long double **data = new long double *[nx]; 
long double **data_read = new long double *[nx]; 
for (int i = 0; i < nx; i++) {
    data[i] = new long double [ny];
    data_read[i] = new long double [ny];
}

data[4][4] = 10.0;
printf("%LF\n", data[4][4]);

FILE *file = fopen("data", "wb");
fwrite(data, nx * ny * sizeof(data), 1, file);
fclose(file);

file = fopen("data", "rb");
fread(data, nx * ny * sizeof(data_read), 1, file );
fclose(file);

printf("%LF\n", data_read[4][4]);
Run Code Online (Sandbox Code Playgroud)

但是data[4][4] != data_read[4][4],因为从文件中读取后data_read[4][4]=0.0.

谁知道我做错了什么?

Who*_*aig 8

您需要单独编写指针数组中的每一行.批量写入不适用于假二维数组(或nD)的指针到指针实现.

写作:

for (int i=0; i<nx; ++i)
    fwrite(data[i], sizeof(data[i][0]), ny, file);
Run Code Online (Sandbox Code Playgroud)

阅读:

for (int i=0; i<nx; ++i)
    fread(data[i], sizeof(data[i][0]), ny, file);
Run Code Online (Sandbox Code Playgroud)

坦率地说,你是(非)幸运的,这个过程并没有完全崩溃,因为你正在为你的磁盘文件写一堆内存地址(一个十六进制转储会向你显示),并且很可能已经走到了你的末尾.两个操作期间的指针数组分配.

也就是说,我开始学习标准的C++ IO库,而不是在C++世界中使用C代码(或者在这个问题上修复标签).


单块写/读

您询问是否可以将此作为单个块读/写来执行.答案是肯定的,但您必须连续分配内存.如果你仍然想要一个指向指针的数组,你当然可以使用一个.虽然我建议使用std::vector<long double>数据缓冲区,但以下内容将演示我所引用的内容:

int main()
{
    int nx = 10, ny = 10;

    long double *buff1 = new long double[nx * ny];
    long double *buff2 = new long double[nx * ny];

    long double **data = new long double *[nx];
    long double **data_read = new long double *[nx];

    for (int i = 0; i < nx; i++)
    {
        data[i] = buff1 + (i*ny);
        data_read[i] = buff2 + (i*ny);
    }

    data[4][4] = 10.0;
    printf("%LF\n", data[4][4]);

    FILE *file = fopen("data.bin", "wb");
    fwrite(buff1, sizeof(*buff1), nx * ny, file);
    fclose(file);

    file = fopen("data.bin", "rb");
    fread(buff2, sizeof(*buff2), nx * ny, file );
    fclose(file);

    printf("%LF\n", data_read[4][4]);

    // delete pointer arrays
    delete [] data;
    delete [] data_read;

    // delete buffers
    delete [] buff1;
    delete [] buff2;
}
Run Code Online (Sandbox Code Playgroud)

产量

10.000000
10.000000
Run Code Online (Sandbox Code Playgroud)

使用std::vector<>for RAII解决方案

所有这些分配都会变得混乱,坦率地说容易出问题.考虑一下这有何不同:

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

int main()
{
    int nx = 10, ny = 10;

    // buffers for allocation
    std::vector<long double> buff1(nx*ny);
    std::vector<long double> buff2(nx*ny);

    // holds pointers into original
    std::vector<long double*> data(nx);
    std::vector<long double*> data_read(nx);

    for (int i = 0; i < nx; i++)
    {
        data[i] = buff1.data() + (i*ny);
        data_read[i] = buff2.data() + (i*ny);
    }

    data[4][4] = 10.0;
    std::cout << data[4][4] << std::endl;

    std::ofstream ofp("data.bin", std::ios::out | std::ios::binary);
    ofp.write(reinterpret_cast<const char*>(buff1.data()), buff1.size() * sizeof(buff1[0]));
    ofp.close();

    std::ifstream ifp("data.bin", std::ios::in | std::ios::binary);
    ifp.read(reinterpret_cast<char*>(buff2.data()), buff2.size() * sizeof(buff2[0]));
    ifp.close();

    std::cout << data_read[4][4] << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)