MST
星途 面试题库

面试题:C++ 利用指针在文件操作时对二进制文件进行复杂数据结构读写

假设有一个自定义的复杂数据结构,例如包含多个不同类型成员(int、float、自定义结构体等)的结构体。要求使用 C++ 指针在文件操作中,将一组这种结构体数据写入二进制文件,然后再完整无误地读出来。阐述实现过程中涉及指针操作的关键要点,并写出核心代码。
16.7万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

关键要点

  1. 内存对齐:确保结构体在内存中的布局与写入文件时一致,避免因内存对齐问题导致读取数据错误。在 struct 定义前使用 #pragma pack(push, 1) 和定义后使用 #pragma pack(pop) 来指定按 1 字节对齐。
  2. 指针类型转换:在写入和读取数据时,需要将结构体指针正确转换为 char* 类型,以确保按字节操作。
  3. 文件操作模式:使用二进制模式打开文件,写入使用 ios::binary | ios::out,读取使用 ios::binary | ios::in

核心代码

#include <iostream>
#include <fstream>

// 自定义结构体
struct CustomStruct {
    int id;
    float value;
    struct InnerStruct {
        char name[20];
        int code;
    } inner;
};

void writeDataToFile(const CustomStruct* data, int count, const char* filename) {
    std::ofstream file(filename, std::ios::binary | std::ios::out);
    if (!file.is_open()) {
        std::cerr << "无法打开文件进行写入" << std::endl;
        return;
    }
    for (int i = 0; i < count; ++i) {
        file.write(reinterpret_cast<const char*>(&data[i]), sizeof(CustomStruct));
    }
    file.close();
}

CustomStruct* readDataFromFile(int& count, const char* filename) {
    std::ifstream file(filename, std::ios::binary | std::ios::in);
    if (!file.is_open()) {
        std::cerr << "无法打开文件进行读取" << std::endl;
        return nullptr;
    }
    file.seekg(0, std::ios::end);
    std::streampos fileSize = file.tellg();
    file.seekg(0, std::ios::beg);
    count = fileSize / sizeof(CustomStruct);
    CustomStruct* data = new CustomStruct[count];
    file.read(reinterpret_cast<char*>(data), fileSize);
    file.close();
    return data;
}

int main() {
    CustomStruct data[] = {
        {1, 3.14f, {"Alice", 101}},
        {2, 2.71f, {"Bob", 102}}
    };
    const int count = sizeof(data) / sizeof(data[0]);
    writeDataToFile(data, count, "data.bin");

    int readCount;
    CustomStruct* readData = readDataFromFile(readCount, "data.bin");
    if (readData) {
        for (int i = 0; i < readCount; ++i) {
            std::cout << "ID: " << readData[i].id
                      << ", Value: " << readData[i].value
                      << ", Name: " << readData[i].inner.name
                      << ", Code: " << readData[i].inner.code << std::endl;
        }
        delete[] readData;
    }
    return 0;
}