c++ - 使用二进制文件访问违规读取位置

标签 c++ binaryfiles access-violation reinterpret-cast

首先,我知道有类似问题的帖子,但我无法在任何帖子中找到适合我的解决方案。

这是一项使用二进制和文本文件存储“公司销售数据”的编程作业。 (部门名称、季度、销售额),然后在二进制数据文件中查找指定记录并显示。

以下是我的代码的重要部分:

#include stuff
...

// Struct to hold division data
struct DIVISION_DATA_S
{
    string divisionName;
    int quarter;
    double sales;
};

int main()
{
    ...

    // Open the data file
    fstream dataFile;
    dataFile.open(dataFilePath, ios::in | ios::out | ios::binary);

    ... Get data from user, store in an instance of my struct ...

    // Dump struct into binary file
    dataFile.write(reinterpret_cast<char *>(&divisionData), sizeof(divisionData));        

    // Cycle through the targets file and display the record from divisiondata.dat for each entry
while(targetsFile >> targetDivisionName)
{       
    int targetQuarter;  // Target quarter
    string targetQuarterStr;
    targetsFile.ignore();   // Ignore the residual '\n' from the ">>" read
    getline(targetsFile, targetQuarterStr);
    targetQuarter = atoi(targetQuarterStr.c_str()); // Parses into an int

    cout << "Target: " << targetDivisionName << " " << targetQuarter << endl;

    // Linear search the data file for the required name and quarter to find sales amount
    double salesOfTarget;
    bool isFound = false;
    while (!isFound && !dataFile.eof())
    {
        cout << "Found division data: " << targetDivisionName << " " << targetQuarter << endl;
        DIVISION_DATA_S divisionData;

        // Read an object from the file, cast as DIVISION_DATA_S
        dataFile.read(reinterpret_cast<char *>(&divisionData), sizeof(divisionData));
        cout << "Successfully read data for " << targetDivisionName << " " << targetQuarter << endl
            << "Name: " << divisionData.divisionName << ", Q: " << divisionData.quarter << ", "
            << "Sales: " << divisionData.sales << endl;

        // Test for a match of both fields
        if (divisionData.divisionName == targetDivisionName && divisionData.quarter == targetQuarter)
        {
            isFound = true;
            cout << "Match!" << endl;
            salesOfTarget = divisionData.sales;
        }
    }
    if (!isFound)   // Error message if record is not found in data file
    {
        cout << "\nError. Could not find record for " << targetDivisionName
            << " division, quarter " << targetQuarter << endl;
    }
    else
    {
        // Display the corresponding record
        cout << "Division: " << targetDivisionName << ", Quarter: " << targetQuarter
            << "Sales: " << salesOfTarget << endl;
        totalSales += salesOfTarget;    // Add current sales to the sales accumulator
        numberOfSalesFound++;   // Increment total number of sales found
    }
}

很抱歉 while 循环缺少缩进,复制/粘贴搞砸了。

我的问题出现在尝试访问从二进制文件中读取的信息时。例如,当它试图执行我为调试添加的 cout 语句时,它给我这个错误:

Unhandled exception at 0x0FED70B6 (msvcp140d.dll) in CorporateSalesData.exe: 0xC0000005: Access violation reading location 0x310A0D68.

现在,从我读到的内容来看,这似乎意味着某些东西正试图从内存的极低区域读取,也就是某处某处与空指针有关,但我无法想象那会怎样出现。整个读取操作完全是从我的教科书中复制的,我不知道 reinterpret_chast 是什么,更不用说它是如何工作的或者如何用它修复错误了。请帮忙?

编辑:感谢所有帮助。为了避免复杂化或使用我不完全理解的东西,我将切换到 divisionName 的 c 字符串。

最佳答案

dataFile.write(reinterpret_cast<char *>(&divisionData), sizeof(divisionData)); 

仅当您具有 POD 类型时才有效。当你有一个 std::string 时它不起作用。您需要使用以下内容:

// Write the size of the string.
std::string::size_type size = divisionDat.divisionName.size();
dataFile.write(reinterpret_cast<char*>(&size), sizeof(size));

// Now write the string.
dataFile.write(reinterpret_cast<char*>(divisionDat.divisionName.c_str()), size);

// Write the quarter and the sales.
dataFile.write(reinterpret_cast<char*>(&divisionDat.quarter), sizeof(divisionDat.quarter));
dataFile.write(reinterpret_cast<char*>(&divisionDat.sales), sizeof(divisionDat.sales));

更改读取调用以匹配写入调用。

关于c++ - 使用二进制文件访问违规读取位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37972036/

相关文章:

c++ - 计算lg(N!) : Anyone have a Better Recursive Method?

c++ - cpp的一些基本问题

python - Matlab -> Python。从磁盘读取异构一维二进制数组

java - 使用Java读取二进制文件并将其转换为char文件

dll - vc6中STL映射分配错误

c - 在 C 中设置用于二分搜索的结构和节点,内存违规

c++ - 带有自定义消息的基于模板的编译时断言只能在某些编译器中编译

c++ - 在 C/C++ 中#include 头文件

java - 如何写入/读取表示对象的二进制文件?

c++ - 在 tesseract、c++ 中释放 char* 时发生访问冲突