【问题标题】:I'm getting Read access violation while accessing objects from file C++.从文件 C++ 访问对象时出现读取访问冲突。
【发布时间】:2018-08-31 11:33:15
【问题描述】:

在下面的类中,错误出现在 init 函数中,我将存储在文件中的类对象加载到向量项中。

class Item
{
std::string item_code;
std::string item_name;
std::string unit_name;
unsigned int price_per_unit;
double discount_rate;
static std::vector<Item> Items;
friend std::ostream& operator<< (std::ostream&, Item&);

public:
static void PrintAll();
static void Init();
~Item();
};

默认构造函数是从用户读取数据并写入文件的构造函数。下面是默认构造函数的代码。

Item::Item(int a)
{
std::cout << "Item name : ";
std::getline(std::cin, item_name);
std::cout << "Unit (Kg/g/Qty) : ";
std::getline(std::cin, unit_name);
std::cout << "Price per unit : ";
std::cin >> price_per_unit;
std::cout << "Discount Rate : ";
std::cin >> discount_rate;
std::cin.ignore();
std::cout << "Product code (has to be unique) : ";
std::getline(std::cin, item_code);

std::ofstream outfile;
outfile.open("Files\\Items.txt", std::ios::out | std::ios::app);
outfile.write((char*)&(*this), sizeof(Item));
outfile.close();
}

下面是引发读取访问冲突的 Init() 函数。

void Item::Init()
{
std::ifstream infile("Files\\Items.txt", std::ios::in);
if (!infile.is_open())
{
    std::cout << "Cannot Open File \n";
    infile.close();
    return;
}
else
{
    Item temp;
    while (!infile.eof())
    {
        infile.read((char*)&temp, sizeof(temp));
        Item::Items.push_back(temp);
    }
}
infile.close();
}

即使我正在检查 eof,也会引发读取访问冲突。请给我一些关于这个问题的建议。

【问题讨论】:

  • Items.txt 看起来像什么?你试图直接读入Item,我的直觉说这不是你真正想要的。
  • Item::Items.push_back(temp); ?
  • 您将无法以这种方式阅读。 std::string 是一个本身具有指针的对象。你不能只是把它写成一个块来读。
  • 我已经添加了我写入文件的部分。
  • @ThomasMartin 将这个程序实例用来表示这个特定内存空间中的数据的内部表示写入文件。一旦发生任何变化,它就毫无意义。你不应该这样做。如果要将字符串写入文件,请编写代码以将字符串写入文件——不要将随机的内存块写入文件。

标签: c++ c++11


【解决方案1】:
    infile.read((char*)&temp, sizeof(temp));

这会用文件中的垃圾填充temp 对象。它应该包含有效的std::string 对象,并且文件中的任何内容都不可能是有效的std::string 对象。如果你不明白为什么,考虑创建一个有效的std::string 对象需要分配内存来保存字符串数据——这就是std::string 构造函数所做的。从文件中读取数据不可能做到这一点。

文件是字节流。要将数据写入文件,您需要定义某种方式将该数据表示为字节流。如果它是可变长度,则需要对其长度进行编码。要重新读回它,您还需要处理可变长度的情况。您需要将文件数据转换为适当的内部表示,例如std::string。这称为“序列化”。

【讨论】:

  • 我已经添加了我将对象写入文件的部分。你能看一下吗>
  • @ThomasMartin 它将无意义的垃圾写入文件。写入实际字符串数据的代码在哪里?读者应该如何知道要读取多少字节?如果sizeof(temp) 小于字符串数据的长度怎么办?这在各方面都是错误的。
  • 我明白。我将更改代码并写为字符串
  • 您将需要处理字符串的长度可能会以某种方式发生变化的事实。最简单的方法是设置最大大小并始终为每个字符串读取/写入那么多字节。
【解决方案2】:

std::string 的大小是可变的,你可以试试下面的定义

char item_code[20];
char item_name[20];
char unit_name[20];

【讨论】:

    猜你喜欢
    • 2014-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-19
    • 2018-05-19
    • 1970-01-01
    相关资源
    最近更新 更多