You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++文本文件读取及学生数据库程序读取失败问题求助

解决C++学生数据库文本文件读取失败的问题

我仔细看了你的代码,发现文件读取功能失效是多个逻辑错误叠加导致的,咱们一步步拆解问题,再给出修复方案:

核心问题分析

  • 学生数组生命周期错误:你把students stud[100];定义在了do-while循环内部,这意味着每次循环都会创建一个全新的空数组,之前添加的学生数据会完全丢失,哪怕读取文件成功也没法保留。
  • 读取逻辑混乱:你打开了StudentFile.txt,但根本没从文件里读取数据到stud数组,反而直接遍历本地的空数组;最后只读取了一个s对象却完全没用到它,而且你根本没写过数据到这个文件,文件本身是空的自然读不出内容。
  • 读取方式不匹配:你用read((char*)&s, sizeof(s))做二进制读取,但如果文件是文本格式(或者从未写入过),这种方式会读取到无效数据。
  • 缺少持久化逻辑:代码只有添加记录到内存的功能,没有把数据写入文件的步骤,文件里根本没有学生数据。

修复后的完整代码

下面是修复后的代码,我标注了关键改动:

#include<string>
#include<iomanip>
#include<fstream>
#include<cstring>
#include<cassert>
#include<iostream>
#include<conio.h>
using namespace std;

class students {
public:
    char name[50];
    char sname[45];
    int idno;
    char cours[40];
    int age;
    int modules;
    void read_data();
    void display();
    // 添加:从文本文件读取单条学生数据的函数
    void read_from_file(ifstream& in);
    // 添加:写入单条学生数据到文本文件的函数
    void write_to_file(ofstream& out);
}s;

void students::read_data() {
    cout<<"Enter name :";
    cin>>name;
    cout<<"Enter Surname : ";
    cin>>sname;
    cout<<"Enter course : ";
    cin>>cours;
    cout<<"Enter age :";
    cin>>age;
    cout<<"Enter modules:";
    cin>>modules;
}

void students::display() {
    cout<<"-----------------------------------------------"<<endl;
    cout<<"Student ID no : "<<idno<<endl;
    cout<<"Student name is :"<<name<<endl;
    cout<<"Student Surname is : "<<sname<<endl;
    cout<<"Student course is :"<<cours<<endl;
    cout<<"Student age is :"<<age<<endl;
    cout<<"Student modules are:"<<modules<<endl;
    cout<<"----------------------------------------------"<<endl;
}

// 从文本文件读取单条学生数据
void students::read_from_file(ifstream& in) {
    in >> idno >> name >> sname >> cours >> age >> modules;
}

// 写入单条学生数据到文本文件
void students::write_to_file(ofstream& out) {
    out << idno << " " << name << " " << sname << " " << cours << " " << age << " " << modules << endl;
}

int main() {
    char dow;
    int arr=0;
    // 关键改动:将学生数组移到循环外,保证数据在循环间不丢失
    students stud[100];

    do{
        cout<<"Press 1 Enter record \n";
        cout<<"Press 2 Display records (from memory)\n";
        cout<<"Press 3 Save records to file\n";
        cout<<"Press 4 Load records from file\n";
        cout<<"\n\t Select option::";
        int sw;
        cin>>sw;
        switch(sw) {
            case 1: {
                cout<<"\n Enter the data of the student no "<<arr+1<<" is :\n";
                cout<<"\t Enter the Roll No = ";
                int id;
                cin>>id;
                // 优化ID重复检查逻辑
                bool idExists = false;
                for(int j=0; j<arr; j++) {
                    if(id == stud[j].idno) {
                        idExists = true;
                        break;
                    }
                }
                if(!idExists){
                    stud[arr].idno=id;
                    stud[arr].read_data();
                    arr++;
                } else {
                    cout<<"This Record is Already Entered \n";
                }
            } break;
            case 2: {
                if(arr == 0) {
                    cout<<"No records to display!\n";
                    break;
                }
                cout << "\n-----------------------------------------------" << endl;
                cout << setw(12) << "Rollno ||";
                cout << setw(12) << " Name ||";
                cout << setw(12) << " Surname || ";
                cout << setw(12) << "Age ||";
                cout << setw(12) << " Course ||";
                cout << setw(12) << " Module ||";
                for(int k = 0; k < arr; k++) {
                    cout << "\n";
                    cout << setw(5) << stud[k].idno;
                    cout << setw(15) << stud[k].name;
                    cout << setw(14) << stud[k].sname;
                    cout << setw(14) << stud[k].age;
                    cout << setw(12) << stud[k].cours;
                    cout << setw(14) << stud[k].modules;
                }
                cout << "\n-------------------------------------------" << endl;
            } break;
            case 3: {
                ofstream outfile("StudentFile.txt", ios::out);
                if(!outfile) {
                    cout<<"Failed to open file for writing!\n";
                    break;
                }
                for(int i=0; i<arr; i++) {
                    stud[i].write_to_file(outfile);
                }
                outfile.close();
                cout<<"Records saved to file successfully!\n";
            } break;
            case 4: { // 对应你提到的case7,可自行调整选项编号
                ifstream infile("StudentFile.txt", ios::in);
                if(!infile) {
                    cout<<"Failed to open file for reading or file does not exist!\n";
                    break;
                }
                arr = 0; // 清空现有内存数据,避免重复加载
                while(infile.peek() != EOF) { // 读取直到文件末尾
                    stud[arr].read_from_file(infile);
                    arr++;
                }
                infile.close();
                cout<<"Records loaded from file successfully! Total records: "<<arr<<"\n";
            } break;
            default:
                cout<<"\t Wrong option Selected ";
                break;
        }
        cout<<"\n\n\t Do You Want to Continue Again [Y/N]";
        cin>>dow;
    } while(dow=='y' || dow=='Y'); // 支持大写Y,提升用户体验
    getch();
    return 0;
}

关键改动说明

  1. 将stud数组移到main函数的do-while循环外,确保添加的学生数据在循环之间不会丢失。
  2. 添加了read_from_file和write_to_file函数,用文本格式读写数据(比二进制更直观,方便调试)。
  3. 新增了case3(保存到文件)和case4(从文件加载),完善了数据持久化逻辑。
  4. 优化了ID重复检查的逻辑,用bool变量让代码更清晰。
  5. 添加了文件打开失败的错误提示,方便排查问题。
  6. 支持大写Y继续循环,提升用户体验。

注意事项

  • 运行程序时,StudentFile.txt会生成在程序的工作目录下(通常是编译后的可执行文件所在文件夹)。
  • 如果需要用二进制读写,需确保写入和读取格式完全一致,且类中无指针类型成员(你的类都是基本类型和字符数组,没问题),但文本格式更适合调试。
  • 可进一步优化:限制学生数量不超过100,给编辑、删除功能添加同步修改文件的逻辑。

内容的提问来源于stack exchange,提问作者young-

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:16:27