如何在C++中将结构体写入文件并读取文件?

pw9qyyiw  于 2023-08-09  发布在  其他
关注(0)|答案(4)|浏览(133)

我有一个结构体,并使用write()将其写入文件。

struct PointFull {
    double lat;
    double lon;
};

PointFull item;
void* buffer = malloc(sizeof (item));
int fd = open("output", O_WRONLY | O_CREAT, S_IWUSR | S_IRUSR);
if (fd < 0) {
    printf("Error opening file\n");
    return 1;
}
memcpy(buffer, &item, sizeof (item));
write(fd2, buffer, sizeof (item));

字符串
现在我有一个名为“输出”的文件在硬盘上,然后我想读取文件来测试数据。

int fd2 = open("output", O_RDONLY, S_IWUSR | S_IRUSR);
if (fd2 < 0) {
    printf("Error opening file\n");
    return 1;
}
void* bufferRead;
bufferRead = malloc(100);
read(fd2, bufferRead,100);


目前,我有bufferRead,但我不知道如何读取缓冲区插入数据到结构?

d6kp6zgx

d6kp6zgx1#

1.您宁愿分配大小为sizeof(PointFull)的缓冲区。因为如果结构体的大小被改变,变得比你硬编码的大小更大,那么你就会得到一个bug。
1.除非你真的需要使用动态内存,否则使用本地缓冲区。我假设在您的代码中并不真正需要分配。只是你可能很容易忘记释放内存,而缓冲区在函数返回时会自动删除。

int fd2 = open("output", O_RDONLY, S_IWUSR | S_IRUSR);
if (fd2 < 0) {
    printf("Error opening file\n");
    return 1;
}
char bufferRead[sizeof(PointFull)];
read(fd2, bufferRead, sizeof(bufferRead));
//Now as you've read it, just cast the memory to struct, and assign it
item = *reinterpret_cast<PointFull*>(bufferRead);
//okay, now item holds the file content, you no longer need the buffer

字符串
还要注意:你的结构可能会通过插入一个填充来对齐。虽然我不认为PointFull会是这种情况,但无论如何,当你需要像这里这样序列化结构时,你最好用#pragma pack声明它,以不允许填充。例如:

#pragma pack(push, 1) // exact fit - no padding
struct PointFull {
    double lat;
    double lon;
};
#pragma pack(pop) //back to whatever the previous packing mode was

67up9zun

67up9zun2#

既然你已经标记了C++

#include <iostream>
#include <fstream>
using namespace std;

struct PointFull {
    double lat;
    double lon;

    PointFull(double lat_in = 0, double lon_in = 0) 
        : lat(lat_in), lon(lon_in) {}
};

int main() {
    PointFull item(123123, 123123);

    cout << "Writing to disk" << endl;
    ofstream fout("saved_point.txt");
    fout << item.lat << ' ' << item.lon;
    fout.close();

    cout << "Reading from disk" << endl;
    PointFull item_from_disk;
    ifstream fin("saved_point.txt");
    fin >> item_from_disk.lat >> item_from_disk.lon;
    fin.close();

    cout << "From RAM and then disk" << endl;
    cout << item.lat << ' ' << item.lon << endl;
    cout << item_from_disk.lat << ' ' << item_from_disk.lon << endl;

    return 0;
}

字符串

mepcadol

mepcadol3#

  • 可以使用fwrite和fread将数据写入文件和从文件读取数据。

下面是相同的示例代码。

#include <stdio.h>

 struct PointFull
 {
    int number;
    char text[10];
    double real_number;
 };

 int main()
{
 struct PointFull  data = {1, "Hello!", 3.14159}, read_data;
 FILE *fout = fopen("file_path", "w");
 fwrite(&data, sizeof(PointFull ), 1, fout);
 //   fprintf(fout, "%d %s %f",data.number, data.text, data.real_number);
 fclose(fout);

 FILE* fin = fopen("file_path", "r");
 fread(&read_data, sizeof(PointFull ), 1, fin);
 printf("%d %s %lf\n", read_data.number, read_data.text, read_data.real_number);
 fclose(fin);
 return 0;
}

字符串

  • 如果你使用fwrite,数据将以二进制或ascii格式写入。要读取这些数据,你必须使用fread。
  • 如果你使用fprintf和fscanf,数据将以人类可编辑的格式存储。
sd2nnvve

sd2nnvve4#

MIT有一个名为'drake'的库具有此功能。您必须采取一些步骤来序列化结构,但它们的文档似乎相当不错!

相关问题