如何让C++中写入stu1.txt的student类数据变为可读格式?
解决stu1.txt文件内容乱码(不可读)的问题
你的问题核心在于用二进制方式写入了对象数据,而文本编辑器只能解析文本格式的内容,所以打开文件会看到乱码。下面一步步帮你解决:
问题根源
你当前用outFile.write((char *)&st, sizeof(student));直接把student对象的内存二进制数据写入文件,这种方式适合程序内部的序列化(比如后续用二进制读取还原对象),但完全不适合人类可读的文本格式。比如int类型的rollno在内存中是4字节的二进制值,不是"123"这样的文本字符,所以打开文件会显示乱码。
解决方案:改成文本模式写入
要让文件内容可读,需要把student的每个成员变量以文本字符串的形式写入文件,比如用<<运算符输出每个字段,并用分隔符(比如逗号、换行)区分不同字段和记录。
1. 修改write_student函数
把原来的二进制写入代码替换成文本写入,同时修复代码里的重复打开/关闭文件的错误:
void write_student() { student st; int nu, fla = 0; ofstream outFile; outFile.open("stu1.txt", ios::app); // 以追加模式打开文本文件 cout << "Enter roll number"; cin >> nu; cout << "Checking for constraint violation......"; fla = pkey(nu); if (fla == 0) { st.getdata(); // 文本方式写入每个成员变量,用逗号分隔字段,换行分隔记录 outFile << st.rollno << "," << st.name << "," << st.p_marks << "," << st.c_marks << "," << st.m_marks << "," << st.e_marks << "," << st.cs_marks << "\n"; cout << "\n\nStudent record Has Been Created "; cin.ignore(); } else { cout << "\n\nPRIMARY KEY CONSTRAINT VIOLATED\n"; } outFile.close(); // 统一在最后关闭文件 getch(); }
2. 调整student类的成员访问权限
上面的代码需要访问student的私有成员,你可以选择两种方式:
- 直接把成员改为
public(简单直接):
class student { public: int rollno; char name[50]; int p_marks, c_marks, m_marks, e_marks, cs_marks; float per; char grade; void calculate(); public: void getdata(); void getdata1(); void showdata(); void show_tabular(); int retrollno(); };
- 添加公共getter方法(更符合面向对象封装原则):
class student { int rollno; char name[50]; int p_marks, c_marks, m_marks, e_marks, cs_marks; float per; char grade; void calculate(); public: void getdata(); void getdata1(); void showdata(); void show_tabular(); int retrollno(); // 添加getter方法 int getRollno() const { return rollno; } const char* getName() const { return name; } int getPMarks() const { return p_marks; } int getCMarks() const { return c_marks; } int getMMarks() const { return m_marks; } int getEMarks() const { return e_marks; } int getCSMarks() const { return cs_marks; } };
使用getter的话,写入代码要改成:
outFile << st.getRollno() << "," << st.getName() << "," << st.getPMarks() << "," << st.getCMarks() << "," << st.getMMarks() << "," << st.getEMarks() << "," << st.getCSMarks() << "\n";
3. 后续读取的对应调整
如果之后要读取这个文本文件的内容,需要用ifstream读取每行,再分割字符串解析字段,还原成student对象,示例代码:
void read_student() { ifstream inFile("stu1.txt"); string line; while (getline(inFile, line)) { stringstream ss(line); string token; student st; // 解析rollno getline(ss, token, ','); st.rollno = stoi(token); // 解析name getline(ss, token, ','); strcpy(st.name, token.c_str()); // 解析分数字段,以此类推 getline(ss, token, ','); st.p_marks = stoi(token); // ... 其他字段的解析 st.showdata(); } inFile.close(); }
效果展示
修改后,stu1.txt里的内容会变成人类可读的文本格式,类似:
101,Alice,85,90,78,88,92 102,Bob,75,82,80,79,85
内容的提问来源于stack exchange,提问作者Skanda Bharadwaj
相关产品推荐
相关产品推荐

