代码之家  ›  专栏  ›  技术社区  ›  Vladyslav Oliinyk

用直接访问c读取文件++

c++
  •  -1
  • Vladyslav Oliinyk  · 技术社区  · 7 年前

    初始任务:创建一个程序来添加产品及其特性。功能可以更新。可以删除商品本身并显示所有产品的列表。

    我有一个有4个参数的结构。我需要在一个文件中存储(写入)一个新记录,然后能够按编号id读取该记录并对该记录执行某些操作。代码:

    #include <iostream>
    #include <fstream>
    #include <iomanip>
    #include <stdlib.h>
    
    using namespace std;
    
    
    struct hardwareData {
        int id;
        char name[50];
        int quantity;
        float price;
    };
    
    int enterChoice(void);
    void newRecord(fstream&);
    void updateRecord(fstream&);
    void outputRecord(fstream&);
    void deleteRecord(fstream&);
    void clearData(fstream&);
    void outputLine(ostream&, hardwareData);
    
    int main() {
    
        fstream inOutHardware("hardware.dat", ios::in | ios::out);
    
        if (!inOutHardware)
        {
            cerr << "Error." << endl;
            exit(1);
        }
    
    int current_choice;
    inOutHardware.clear();
    while (((current_choice = enterChoice()) != 0))
    {
    
        switch (current_choice)
        {
        case 1:
            newRecord(inOutHardware);
            break;
        case 2:
            updateRecord(inOutHardware);
            break;
        case 3:
            deleteRecord(inOutHardware);
            break;
        case 4:
            outputRecord(inOutHardware);
            break;
        case 5:
            int num;
            cout << "Clear? (1 - так / 0 - нi)"         
            << endl << "Your choice - ";
            cin >> num;
            if (num == 1) {
                clearData(inOutHardware);
                cout << "succ!" << endl;
            }
            else {
                cout << "canceled" << endl;
            }
    
            break;
        default:
            cerr << "err" << endl;
            break;
        }
    
    }
    
    inOutHardware.close();
    system("pause");
    return 0;
    }
    
    void newRecord(fstream &insertInFile)
    {
        cout << "Input number (1-100): ";
    
        hardwareData hardware;
    
        int id;
        cin >> id;
        insertInFile.seekg((id - 1) + sizeof(hardware));
    
        insertInFile.read((char *)&hardware, sizeof(hardware));
    
        if (hardware.id == 0)
        {
            cout << "Input data" << endl;
            cin >> hardware.name >> hardware.quantity >> hardware.price;
            hardware.id = id;
            insertInFile.seekp((id - 1) * sizeof(hardwareData));
            insertInFile.write((char *)&hardware, sizeof(hardwareData));
    
        }
        else
            cerr << "№ " << id
            << " already have info" << endl;
    }
    
    void updateRecord(fstream &updateFile)
    {
        int id;
    
        do
        {
            cout << "Input number for update: ";
            cin >> id;
        } while (id < 1 || id > 100);
    
        hardwareData hardware;
        updateFile.seekg((id - 1) * sizeof(hardware));
    
        updateFile.read((char *)&hardware, sizeof(hardware));
    
        if (hardware.id != 0)
        {
            outputLine(cout, hardware);
            cout << endl << "Input quan and price : ";
    
            int quan;
            float price;
            cin >> quan;
            cin >> price;
            hardware.quantity = quan;
            hardware.price = price;
            outputLine(cout, hardware);
    
            updateFile.seekp((id - 1) * sizeof(hardware));
            updateFile.write((char *)&hardware, sizeof(hardware));
        }
        else
            cerr << " № " << id
            << " empty " << endl;
    }
    
    void deleteRecord(fstream &deleteFromFile)
    {
        cout << "Input number for delete (1-100): ";
    
        int id;
        cin >> id;
        deleteFromFile.seekg((id - 1) * sizeof(hardwareData));
    
        hardwareData hardware;
        deleteFromFile.read((char *)&hardware, sizeof(hardwareData));
    
        if (hardware.id != 0)
        {
            hardwareData blankhw = { 0, " ", 0,  0 };
    
            deleteFromFile.seekp((id - 1) * sizeof(hardware));
            deleteFromFile.write((char*)&blankhw, sizeof(hardware));
            cout << "№ " << id << " deleted" << endl;
    
        }
        else
            cout << "№ " << id << " empty" << endl;
    }
    
    void outputRecord(fstream &printRecord)
    {
    
        cout << setiosflags(ios::left) << setw(6) << "ID"
            << setw(16) << "NAME" << setw(11) << "QUANTITY"
            << setiosflags(ios::right) << setw(10) << "PRICE" << endl;
        printRecord.seekg(0);
    
        hardwareData hardware;
        printRecord.read((char*)&hardware, sizeof(hardware));
    
        while (!printRecord.eof())
        {
            if (hardware.id != 0)
                outputLine(cout, hardware);
    
            printRecord.read((char*)&hardware, sizeof(hardware));
        }
    }
    
    void clearData(fstream &record) {
        hardwareData blankHardware = { 0, "", 0, 0.0 };
    
        record.seekp(0);
        for (int i = 1; i <= 100; i++)
            record.write((char *)&blankHardware, sizeof(blankHardware));
    }
    
    
    int enterChoice(void)
    
    {
        cout << "Виберiть опцiю" << endl
        << " 1 - Add " << endl
        << " 2 - update" << endl
        << " 3 - delete" << endl
        << " 4 - output" << endl
        << " 5 - clear" << endl
        << " 0 - exit" << endl;
    
        int choice;
        cin >> choice;
    
        return choice;
    }
    
    void outputLine(ostream &output, hardwareData c)
    {
    
        output << setiosflags(ios::left) << setw(6) << c.id
        << setw(16) << c.name << setw(11) << c.quantity
        << setiosflags(ios::showpoint | ios::right)
        << setw(10) << setprecision(2) << c.price << endl;
    }
    

    错误:当我第一次单击文件中所有数据的输出时,所有内容都以名义工作,下一次,未知字符将无限次显示。 Infinity loop

    1 回复  |  直到 7 年前
        1
  •  4
  •   Chris Uzdavinis    7 年前

    您有一个重复的问题,即不检查操作是否成功,然后使用未初始化的数据,因为没有发生初始化。例如:

    hardwareData hardware;
    
    int id;
    cin >> id;
    insertInFile.seekg((id - 1) + sizeof(hardware));
    
    insertInFile.read((char *)&hardware, sizeof(hardware));
    
    if (hardware.id == 0)
    {
    

    hardwareData 没有构造函数,因此硬件未初始化,可能包含垃圾。它不是零初始化的,除非您导致这种情况发生,例如:

    hardwareData hardware{};
    

    id 是未初始化的,又像是装垃圾。如果从cin读取失败,id将保留一个垃圾值。将id初始化为零。

    hardware

    然后你检查一下 hardware.id 为零表示该记录不存在,但如果它包含垃圾,则无法可靠地从其任何成员中提取任何意义。

    我没有看得更远,所以你可能还有其他问题,但这些是重要的问题。