C++写入Students.txt出现乱码 预期为姓名数字的问题排查
问题排查与修复方案
错误原因
- 非法二进制序列化非POD类型:
admin类的成员都是string类型,属于动态内存类,内部仅存储指向字符串的指针、长度等元数据,直接用write把对象的内存二进制写入文件,实际写入的是指针地址等二进制数据,不是字符串本身,自然会出现乱码,且这种序列化方式生成的内容没有持久化可用性,下次程序运行读回的指针地址都是无效内存。 - 赋值逻辑错误:
getdata方法中用户输入的内容存到了当前对象的ID、Name、librarian成员,但写入文件的obj对象被赋值的是未初始化的空局部变量id、name、lib,就算序列化逻辑正确,写入的也都是空内容。 - 读取逻辑错误:
showdata方法中把文件内容读到了局部obj对象,但最终输出的是当前对象的成员,永远只能输出上次输入的内容,不是文件存储的真实数据。 - 存储逻辑不符合文本文件要求:
.txt后缀的文件本就应该存储明文内容,用二进制写入内存数据本身就不符合文本文件的使用规范。
修复方案
改用文本流写入明文内容,按行存储每个字段即可,修复后代码如下:
#include <fstream> #include <iostream> #include <string> using namespace std; class admin { public: string ID; string Name; string librarian; void getdata(); void showdata(); }; void admin::getdata() { ofstream file_obj; file_obj.open("Students.txt", ios::app); if (!file_obj.is_open()) { cout << "文件打开失败" << endl; return; } cout << "Enter Student Details......\n\n"; cout << "Enter ID No. : "; cin >> ID; cout << "Enter Full Name : "; cin >> Name; cout << "Enter librarian name. : "; cin >> librarian; // 按行写入明文内容 file_obj << ID << endl; file_obj << Name << endl; file_obj << librarian << endl; file_obj.close(); } void admin::showdata() { ifstream file_obj; file_obj.open("Students.txt", ios::in); if (!file_obj.is_open()) { cout << "文件打开失败" << endl; return; } admin obj; // 逐行读取文件内容 while (getline(file_obj, obj.ID) && getline(file_obj, obj.Name) && getline(file_obj, obj.librarian)) { cout << "\n\n.......Student Details......\n"; cout << "ID No. : " << obj.ID << endl; cout << "Full Name : " << obj.Name << endl; cout << " librarian name. : " << obj.librarian << endl; } file_obj.close(); } int main() { admin myobj; myobj.getdata(); myobj.showdata(); return 0; }
修复说明
- 改用文本流写入可读字符串,生成的
Students.txt为明文,无乱码 - 修正了赋值逻辑,直接写入用户输入的有效内容
- 修正了读取逻辑,输出内容为文件存储的真实数据
- 增加了文件打开校验,避免文件权限不足、路径错误导致的异常
内容的提问来源于stack exchange,提问作者big joe
相关产品推荐
相关产品推荐

