【问题标题】:How to delete stored data in a text file?如何删除文本文件中存储的数据?
【发布时间】:2021-04-22 11:50:55
【问题描述】:

感谢@RemyLebeau,下面的代码基于我原来的代码进行了修改以修复错误。 它很棒,但是出现了一个新问题,当我想使用菜单中的选项 4 删除学生数据时,在输入他们的 ID 后,它说他们的数据已被删除,但事实并非如此。在控制台的末尾,标准错误流 (cerr) 下的消息“从文件读取数据时出错” 不断出现。我所有修复它的尝试都失败了。 error_display

//Project on Student Management
#include <iostream>
#include <fstream>
#include <string>
#include <vector>

using namespace std;

struct Course
{
    string courseName;
    string grade;
    string status;
};

class Student
{
    int id;
    int year;
    float cgpa;
    vector<Course> courses;
    string academic_advisor;
    
public:
    Student();

    void getData();
    void showData() const;
    int getID() const { return id; }

    friend ostream& operator<<(ostream &out, const Student &s);
    friend istream& operator>>(istream &in, Student &s);
};

void writeStr(ostream &out, const string &str)
{
    size_t size = str.size();
    out.write((char*)&size, sizeof(size));
    if (size)
        out.write(str.c_str(), size);
}

void readStr(istream &in, string &str)
{
    str.clear();

    size_t size;
    if (in.read((char*)&size, sizeof(size)))
    {
        if (size > 0)
        {
            str.resize(size);
            in.read(&str[0], size);
        }
    }
}

ostream& operator<<(ostream &out, const Course &c)
{
    writeStr(out, c.courseName);
    writeStr(out, c.grade);
    writeStr(out, c.status);
    return out;
}

istream& operator>>(istream &in, Course &c)
{
    readStr(in, c.courseName);
    readStr(in, c.grade);
    readStr(in, c.status);
    return in;
}

ostream& operator<<(ostream &out, const Student &s)
{
    out.write((char*)&s.id, sizeof(s.id));
    out.write((char*)&s.year, sizeof(s.year));
    out.write((char*)&s.cgpa, sizeof(s.cgpa));
    writeStr(out, s.academic_advisor);

    size_t NumberOfcourses = s.courses.size();
    out.write((char*)&NumberOfcourses, sizeof(NumberOfcourses));

    for(int i = 0; i < NumberOfcourses; ++i)
    {
        if (!(out << s.courses[i]))
            break;
    }

    return out;
}

istream& operator>>(istream &in, Student &s)
{
    s.courses.clear();

    in.read((char*)&s.id, sizeof(s.id));
    in.read((char*)&s.year, sizeof(s.year));
    in.read((char*)&s.cgpa, sizeof(s.cgpa));
    readStr(in, s.academic_advisor);

    size_t NumberOfcourses;
    if (in.read((char*)&NumberOfcourses, sizeof(NumberOfcourses)))
    {
        s.courses.reserve(NumberOfcourses);
        Course c;

        for(size_t i = 0; i < NumberOfcourses; ++i)
        {
            if (in >> c)
                s.courses.push_back(c);
            else
                break;
        }
    }

    return in;
}

Student::Student()
{
    id = 0;
    year = 0;
    cgpa = 0.0f;
}

void Student::getData()
{
    courses.clear();

    cout << "\n\nEnter Student Details......\n";
    cout << "Enter ID No.     : "; cin >> id;
    cout << "Enter Intake Year of the Student: "; cin >> year;
    cout << "Enter number of Taken courses: ";

    size_t NumberOfcourses;
    cin >> NumberOfcourses;
    cin.ignore();

    courses.reserve(NumberOfcourses);
    Course c;

    for(int a = 0; a < NumberOfcourses; ++a)
    {
        cout << "\nEnter Subject Name: ";
        getline(cin, c.courseName);
            
        cout << "Enter Grade of Subject: ";
        getline(cin, c.grade);
            
        cout << "Enter Subject Status: ";
        getline(cin, c.status);

        courses.push_back(c);
    }

    cout << "Enter student CGPA: ";
    cin >> cgpa;
    cin.ignore();

    cout << endl;
    cout << "Enter Name of Academic Advisor of Student: ";
    getline(cin, academic_advisor);
}

void Student::showData() const
{
    cout << "\n\n.......Student Details......\n";
    cout << "ID No.                                   : " << id << endl;
    cout << "Intake Year                              : " << year << endl;
    cout << "Subjects Taken in Previous Semester      : " << endl;
    for(size_t t = 0; t < courses.size(); ++t)
    {
        cout << "\t" << courses[t].courseName << ": " << courses[t].grade << " (" << courses[t].status << ") ";
        cout << endl;
    }
    cout << "CGPA                                     : " << cgpa << endl;
    cout << "Name of academic advisor of Student      : " << academic_advisor << endl;
    cout << endl;
}

void addData()
{
    Student s;
    s.getData();

    ofstream fout("Students.txt", ios::binary|ios::app);
    if (fout << s)
        cout << "\n\nData Successfully Saved to File....\n";
    else
        cerr << "\n\nError Saving Data to File!\n";
}

void displayData()
{
    ifstream fin("Students.txt", ios::binary);

    Student s;
    while (fin >> s)
    {
        s.showData();
    }

    if (fin)
        cout << "\n\nData Reading from File Successfully Done....\n";
    else
        cerr << "\n\nError Reading Data from File!\n";
}

void searchData()
{
    int n;
    cout << "Enter ID Number you want to search for : ";
    cin >> n;    

    ifstream fin("Students.txt", ios::binary);

    Student s;
    bool flag = false;

    while (fin >> s)
    {
        if (n == s.getID())
        {
            cout << "The Details of ID No. " << n << " are: \n";
            s.showData();
            flag = true;
            break;
        }
    }

    if (fin)
    {
        if (!flag)
            cout << "The ID No. " << n << " not found....\n\n";
        cout << "\n\nData Reading from File Successfully Done....\n";
    }
    else
        cerr << "\n\nError Reading Data from File!\n";
}

void deleteData()
{
    int n;
    cout << "Enter ID Number you want to delete : ";
    cin >> n;
    
    ifstream fin("Students.txt", ios::binary);
    ofstream fout("TempStud.txt", ios::binary);
    ofstream tout("TrashStud.txt", ios::binary|ios::app);

    Student s;
    bool flag = false;

    while (fin >> s)
    {
        if (n == s.getID())
        {
            cout << "The Following ID No. " << n << " has been deleted:\n";
            s.showData();
            tout << s;
            flag = true;
        }
        else
        {
            fout << s;
        }
    }

    if (fin)
    {
        if (fout)
        {
            fin.close();
            fout.close();

            if (!flag)
            {
                cout << "The ID No. " << n << " not found....\n\n";
                remove("tempStud.txt");
            }
            else
            {
                remove("Students.txt");
                rename("tempStud.txt", "Students.txt");

                cout << "\n\nData Successfully Deleted from File....\n";
            }
        }
        else
        {
            cerr << "\n\nError Saving Data to File!\n";
        }
    }
    else
    {
        cerr << "\n\nError Reading Data from File!\n";
    }
}


void modifyData()
{
    int n;    
    cout << "Enter ID Number you want to Modify : ";
    cin >> n;
    
    ifstream fin("Students.txt", ios::binary);
    ofstream fout("TempStud.txt", ios::binary);

    Student s;
    bool flag = false;

    while (fin >> s)
    {
        if (n == s.getID())
        {
            cout << "The Following ID No. " << n << " will be modified with new data:\n";
            s.showData();
            cout << "\n\nNow Enter the New Details....\n";
            s.getData();
            flag = true;
        }

        fout << s;
    }
    
    if (fin)
    {
        if (fout)
        {
            fin.close();
            fout.close();

            if (!flag)
            {
                cout << "The ID No. " << n << " not found....\n\n";
                remove("TempStud.txt");
            }
            else
            {
                remove("Students.txt");
                rename("TempStud.txt", "Students.txt");

                cout << "\n\nData Successfully Updated in File....\n";
            }
        }
        else
        {
            cerr << "\n\nError Saving Data to File!\n";
        }
    }
    else
    {
        cerr << "\n\nError Reading Data from File!\n";
    }
}

void project()
{
    int ch;
    do
    {
        system("cls");
        cout << "...............STUDENT MANAGEMENT SYSTEM..............\n";
        cout << "====================SEGI University=================\n";
        cout << "0. Exit from Program\n";
        cout << "1. Write Data to File\n";
        cout << "2. Read Data From File\n";
        cout << "3. Search Data From File\n";
        cout << "4. Delete Data From File\n";
        cout << "5. Modify Data in File\n";
        cout << "Enter your choice  : ";
        cin >> ch;
        system("cls");
        switch (ch)
        {
            case 1: addData(); break;
            case 2: displayData(); break;
            case 3: searchData(); break;
            case 4: deleteData(); break;
            case 5: modifyData(); break;
        }
        system("pause");
    }
    while (ch != 0);
}

int main()
{
    project();
}

【问题讨论】:

  • 我在modifyData() 中看到至少一个关于文件名的错字。我强烈建议使用一个带有名称的全局常量而不是重复它,让编译器完成校对的艰苦工作会容易得多。此外,如果您在 Unix 上工作,文件名中的大小写可能无关紧要,但在 Windows 上却很重要。
  • 当您使用调试器运行代码时,一次一行,您看到显示的代码在做什么?

标签: c++ c++11 c++17


【解决方案1】:

错误是因为 fin (在 deleteData () 函数中)运行到文件末尾,最后 fin 存储 nullptr (布尔转换为 false)这就是 else 语句运行的原因。很明显 while 循环 中断的原因。 要检查文件是否打开,您可以使用 if(fin.is_open()) 用于 fin 并类似地用于 fout,例如 if(fout.is_open())

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-03
    • 2020-08-25
    • 1970-01-01
    • 1970-01-01
    • 2018-02-04
    • 1970-01-01
    • 2017-05-24
    • 1970-01-01
    相关资源
    最近更新 更多