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; }
关键改动说明
- 将
stud数组移到main函数的do-while循环外,确保添加的学生数据在循环之间不会丢失。 - 添加了
read_from_file和write_to_file函数,用文本格式读写数据(比二进制更直观,方便调试)。 - 新增了case3(保存到文件)和case4(从文件加载),完善了数据持久化逻辑。
- 优化了ID重复检查的逻辑,用
bool变量让代码更清晰。 - 添加了文件打开失败的错误提示,方便排查问题。
- 支持大写Y继续循环,提升用户体验。
注意事项
- 运行程序时,
StudentFile.txt会生成在程序的工作目录下(通常是编译后的可执行文件所在文件夹)。 - 如果需要用二进制读写,需确保写入和读取格式完全一致,且类中无指针类型成员(你的类都是基本类型和字符数组,没问题),但文本格式更适合调试。
- 可进一步优化:限制学生数量不超过100,给编辑、删除功能添加同步修改文件的逻辑。
内容的提问来源于stack exchange,提问作者young-
相关产品推荐
相关产品推荐

