Lynn·P 2024-04-30 00:04 采纳率: 100%
浏览 9
已结题

关于#二进制文件输入输出#的问题,如何解决?

本人计算机专业新生,麻烦各位帮忙看一下这段c++代码的文件输入输出部分问题在哪

在定义的file_input函数中,通过传入一个类,以二进制的形式存入文件。
在主函数中,我根据输入的信息动态生成类,用以存储这些信息,并将该类通过调用file_input函数以二进制存入文件中,如此循环直到输入为-1
在file_output函数中,从二进制文件中提取类并调用函数输出信息

但是这样无法将类正确地存入文件中,且输出为乱码,想问一下为什么会出现这种情况,以及如何修正

#include <iostream>
#include <fstream>
#include <cstring>
#include <cstdlib>
using namespace std;

class student
{
    public:
        student();
        student(int id, string name, float grade);
        student(const student &s);
        void print_stu();
        //friend void delete_stu(student *s);
        //friend void modify_stu(student *s);
    private:
        int id;
        string name;
        float grade;
};


student::student()
{
    
}
student::student(int id, string name, float grade)
{
    this -> id = id;
    this -> name = name;
    this -> grade = grade;
}
student::student(const student &s)
{
    id = s.id;
    name = s.name;
    grade = s.grade;
}

void student::print_stu()
{
    cout << "ID: " << id << " " << "Name: " << name << " " << "Grade: " << grade << endl; 
}


void file_input(student s)
{
    s.print_stu();
    fstream file1;
    file1.open("student.dat", ios::out | ios::binary | ios::app);
    
    if(!file1)
    {
        cout << "Cannot open the file" << endl;
        abort();
    }
    
    file1.write((char *)&s, sizeof(s));
    file1.close();
}

void file_output()
{
    fstream file1;
    file1.open("student.dat", ios::in | ios::binary);
    
    if(!file1)
    {
        cout << "Cannot open the file" << endl;
        abort();
    }
    
    student s;
    while(file1.read((char *)&s, sizeof(s)))
    {        
        s.print_stu(); 
    } 
    file1.close();
}


int main()
{
    while(1)
    {
        cout << "1: 输入学生信息" << endl << "2: 显示学生信息" << endl;
    
        int control = -1;
        cin >> control;
        
        if(control == 1)
        {    
            cout << "请输入学生id, 以-1停止输入" << endl;
        
            int id = 0;
            cin >> id;
            while(id != -1)
            {
                cout << "请输入学生姓名,成绩" << endl;
            
                string name;
                float grade;
                cin >> name >> grade;
            
                student *s_ptr = new student(id, name, grade);

                file_input(*s_ptr);
                delete s_ptr;
                s_ptr = NULL;
                
                cout << "请输入学生id, 以-1停止输入" << endl;
                cin >> id;
            }
        
            cout << "输入成功!" << endl;
        }
    
        if(control == 2)
        {
            file_output();
        }
    }
}

  • 写回答

10条回答 默认 最新

  • micthis 2024-04-30 00:42
    关注

    name是string类型,保存到文件时只是保存了一个指向堆中的地址,实际的姓名字符串并没有保存到文件中,将name改成以字符数组存储就行了。
    运行截图:

    img

    img


    代码:

    #include <iostream>
    #include <fstream>
    #include <cstring>
    #include <cstdlib>
    using namespace std;
    class student
    {
        public:
            student();
            student(int id, char name[], float grade);
            student(const student &s);
            void print_stu();
            //friend void delete_stu(student *s);
            //friend void modify_stu(student *s);
        private:
            int id;
            char name[128];
            float grade;
    };
     
    student::student()
    {
        id=0;
        strcpy(name,"noname");
        grade=0;
    }
    student::student(int id, char name[], float grade)
    {
        this -> id = id;
        strcpy(this->name,name);
        this -> grade = grade;
    }
    student::student(const student &s)
    {
        id = s.id;
        strcpy(this->name,s.name);
        grade = s.grade;
    }
    void student::print_stu()
    {
        cout << "ID: " << id << " " << "Name: " << name << " " << "Grade: " << grade << endl; 
    }
     
    void file_input(student s)
    {
        s.print_stu();
        fstream file1;
        file1.open("student.dat", ios::out | ios::binary | ios::app);
        if(!file1)
        {
            cout << "Cannot open the file" << endl;
            abort();
        }
        file1.write((char *)&s, sizeof(s));
        file1.close();
    }
    void file_output()
    {
        fstream file1;
        file1.open("student.dat", ios::in | ios::binary);
        if(!file1)
        {
            cout << "Cannot open the file" << endl;
            abort();
        }
        student s;
        while(file1.read((char *)&s, sizeof(s)))
        {        
            s.print_stu(); 
        } 
        file1.close();
    }
     
    int main()
    {
        while(1)
        {
            cout << "1: 输入学生信息" << endl << "2: 显示学生信息" << endl;
            int control = -1;
            cin >> control;
            if(control == 1)
            {    
                cout << "请输入学生id, 以-1停止输入" << endl;
                int id = 0;
                cin >> id;
                while(id != -1)
                {
                    cout << "请输入学生姓名,成绩" << endl;
                    char name[128];
                    float grade;
                    cin >> name >> grade;
                    student *s_ptr = new student(id, name, grade);
                    file_input(*s_ptr);
                    delete s_ptr;
                    s_ptr = NULL;
                    cout << "请输入学生id, 以-1停止输入" << endl;
                    cin >> id;
                }
                cout << "输入成功!" << endl;
            }
            if(control == 2)
            {
                file_output();
            }
        }
        return 0;
    }
    

    名字用string类型也是可以的,但代码得改成这样:

    #include <iostream>
    #include <fstream>
    #include <cstring>
    #include <cstdlib>
    using namespace std;
    class student
    {
        public:
            student();
            student(int id, string name, float grade);
            student(const student &s);
            void print_stu();
            string& get_name();
            void set_name(string name);
            //friend void delete_stu(student *s);
            //friend void modify_stu(student *s);
        private:
            int id;
            string name;
            float grade;
    };
     
    student::student()
    {
        this->id=0;
        this->name="noname";
        this->grade=0;
    }
    student::student(int id, string name, float grade)
    {
        this -> id = id;
        this -> name = name;
        this -> grade = grade;
    }
    
    student::student(const student &s)
    {
        id = s.id;
        name = s.name;
        grade = s.grade;
    }
    void student::print_stu()
    {
        cout << "ID: " << id << " " << "Name: " << name << " " << "Grade: " << grade << endl; 
    }
    
    string& student::get_name()
    {
        return name;
    }
    
    void student::set_name(string name)
    {
        this->name=name;
    }
    
    void file_input(student s)
    {
        int len;
        string name;
        
        s.print_stu();
        fstream file1;
        file1.open("student2.dat", ios::out | ios::binary | ios::app);
        if(!file1)
        {
            cout << "Cannot open the file" << endl;
            abort();
        }
        file1.write((char *)&s, sizeof(s));
        name=s.get_name();
        len=name.length();
        //写入名字长度
        file1.write((char*)&len,sizeof(len));
        //写入名字
        file1.write(name.c_str(),len);
        file1.close();
    }
    void file_output()
    {
        int len;
        char name[128];
        
        fstream file1;
        file1.open("student2.dat", ios::in | ios::binary);
        if(!file1)
        {
            cout << "Cannot open the file" << endl;
            abort();
        }
        student s;
        while(file1.read((char *)&s, sizeof(s)) && file1.read((char *)&len, sizeof(len)) && file1.read(name, len))
        {        
            name[len]=0;
            s.set_name(name);
            s.print_stu(); 
        } 
        file1.close();
    }
     
    int main()
    {
        while(1)
        {
            cout << "1: 输入学生信息" << endl << "2: 显示学生信息" << endl;
            int control = -1;
            cin >> control;
            if(control == 1)
            {    
                cout << "请输入学生id, 以-1停止输入" << endl;
                int id = 0;
                cin >> id;
                while(id != -1)
                {
                    cout << "请输入学生姓名,成绩" << endl;
                    string name;
                    float grade;
                    cin >> name >> grade;
                    student *s_ptr = new student(id, name, grade);
                    file_input(*s_ptr);
                    delete s_ptr;
                    s_ptr = NULL;
                    cout << "请输入学生id, 以-1停止输入" << endl;
                    cin >> id;
                }
                cout << "输入成功!" << endl;
            }
            if(control == 2)
            {
                file_output();
            }
        }
        return 0;
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(9条)

报告相同问题?

问题事件

  • 系统已结题 5月8日
  • 已采纳回答 4月30日
  • 创建了问题 4月30日

悬赏问题

  • ¥15 关于#windows#的问题:2024年5月15日的win11更新后资源管理器没有地址栏了顶部的地址栏和文件搜索都消失了
  • ¥15 看一下OPENMV原理图有没有错误
  • ¥100 H5网页如何调用微信扫一扫功能?
  • ¥15 讲解电路图,付费求解
  • ¥15 有偿请教计算电磁学的问题涉及到空间中时域UTD和FDTD算法结合的
  • ¥15 vite打包后,页面出现h.createElement is not a function,但本地运行正常
  • ¥15 Java,消息推送配置
  • ¥15 Java计划序号重编制功能,此功能会对所有序号重新排序,排序后不改变前后置关系。
  • ¥15 关于哈夫曼树应用得到一些问题
  • ¥15 使用sql server语句实现下面两个实验(需要代码和运行结果截图)