【问题标题】:Create binray file in constructor在构造函数中创建二进制文件
【发布时间】:2021-09-04 22:52:24
【问题描述】:

我写了一个小的Store,其中包含Item。我创建了两个函数,一是打印文件的内容,一是对记录进行排序并将它们插入回文件中。使用初始化列表,它可以正确显示文件的内容,但说有“文件错误”。如何更正此问题以及在构造函数中创建二进制文件的最佳方法是什么

#pragma once
#include <iostream>
#include <fstream>
#include <cstring>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

struct Item
{
    char name[20];
    int code;
    float price;
    int quantity;

    Item() { code = 0, price = 0, quantity = 0;
    char name1[20] = { 0 }; strcpy_s(name, 20, name1);
    }
    Item(const char* name, int code, float price, int quantity)
    {
        strcpy_s(this->name, strlen(name) + 1, name);
        this->code = code;
        this->price = price;
        this->quantity = quantity;
    }
    friend ostream& operator<<(ostream& os, Item& item)
    {
        os << "Name: " << item.name << endl;
        os << "code: " << item.code << endl;
        os << "price: " << item.price << endl;
        os << "quantity: " << item.quantity << endl << endl;
        return os;
    }
    bool operator!()
    {
        return code != 0;
    }
};
class Store
{
private:
    int size = 100;
    fstream file;
    string fileName;
public:
    Store(string fname);
    ~Store();
    Store& operator+=(Item& myItem);
    friend ostream& operator<<(ostream&, Store&);
    void sortStore();
};
#include "Store.h"
Store::Store(string fname) : file(fname,ios::binary)
    {
    
        Item tmp;
        if (!file)
            cout << "Error with file" << endl;
        for (int i = 0; i < size; i++)
            file.write((char*)&tmp, sizeof(Item));
        //file.close();
        file.open(fname, ios::binary | ios::in | ios::out);
    }
Store::~Store()
{
    file.close();
}
Store& Store::operator+=(Item& myItem)
{
    file.write((char*)&myItem, sizeof(myItem));
    return (*this);
}
ostream& operator<<(ostream& out, Store& store)
{
    Item tmp;
    store.file.seekg(0, ios::beg);
    for (int i = 0; i < store.size; i++)
    {
        store.file.read((char*)&tmp, sizeof(Item));
        if (!tmp)
            cout << i << ": " <<  tmp;
    }
    return out;
}
void Store::sortStore()
{
    Item tmp;
    vector<Item> items;
    file.seekg(0, ios::beg);
    while (!file.eof())
    {
        file.read((char*)&tmp, sizeof(Item));
        items.push_back(tmp);
    }
    sort(items.begin(), items.end(), [](Item& first, Item& second)
        {
            return first.code < second.code;
        });

    file.clear();
    remove("store.dat");
    Store("store.dat");

    file.seekp(0, ios::beg);
    
    for (auto it = items.begin(); it < items.end(); it++)
        file.write((char*)&(*it), sizeof(Item));
}

int main()
{
    Store ourStore("store.dat");
    Item apple("apple", 45, 12.2, 10);
    Item ananas("ananas", 12, 27, 10);
    Item strawberry("strawberry", 1, 24.2, 5);
    Item banana("banana",23,14.2, 12);
    ourStore.operator+=(apple);
    ourStore.operator+=(ananas);
    ourStore.operator+=(strawberry);
    ourStore.operator+=(banana);

    int choice = -1;
    while (choice != 0)
    {
        cout << "1.Sorting, 2 Print" << endl;
        switch (choice)
        {
        case 1:
            cout << "Sorting" << endl;
            ourStore.sortStore();
        case 2:
            cout << "Print" << endl;
            cout << ourStore << endl;
        }
        cin >> choice;
    }



    return 0;
}

【问题讨论】:

  • 你永远不会打开file成员。
  • @molbdnilo 为什么?在构造函数中我写 file.open()
  • 你也写ofstream file(fname, ios::binary);,它声明了一个局部变量。
  • 顺便说一句,重载运算符的意义在于它可以让你写出像ourStore += apple;这样的东西
  • @molbdnilo 我是否必须同时在构造函数 file.close() 中写入,然后再次打开它?

标签: c++ file class


【解决方案1】:

Store::Store中的局部变量file隐藏了成员变量Store::file

你想要一个初始化列表:

Store::Store : file(fname, ios::binary)
{
// ...

【讨论】:

  • 你能通过在初始化列表上写下这个来解释更多的区别吗?为什么当它在构造函数中时,这不起作用
  • @Ronyco123:你是从一本好的教科书中学习 C++ 的吗?这仍然是最好的方法。总之,差别很大。成员初始化器列表确定为成员调用哪些构造函数。由于您没有初始化列表,Store::file 是使用默认构造函数构造的。这不会打开文件。
  • 我现在发布我的构造函数,它有什么问题
  • @Ronyco123:您已将新问题添加为现有问题的答案。那是行不通的;人们不会在答案部分寻找问题。相反,你应该问一个新问题。但在您这样做之前,请确保您有两个简单的测试用例:一个带有一个可以打开文件的局部变量,另一个带有一个不打开文件的成员初始化器列表。
猜你喜欢
  • 1970-01-01
  • 2015-02-21
  • 1970-01-01
  • 1970-01-01
  • 2017-11-11
  • 2013-04-29
  • 2021-02-21
  • 1970-01-01
  • 2017-01-21
相关资源
最近更新 更多