C++写入文件后用记事本打开出现乱码问题咨询
嘿,我来帮你搞明白为啥用记事本打开Student.dat会出现乱码,还有怎么解决这个问题~
为啥记事本打开会乱码?
咱先理清楚核心原因:你用ios::binary模式写入的是二进制数据,而记事本是专门用来解析纯文本文件的工具,两者根本不匹配!
你的Student类对象在内存里是按二进制存储的:
rollno是int类型,占4字节(比如数值1的二进制是0x01 0x00 0x00 0x00,小端模式下),这些字节都是不可打印的控制字符;- 虽然
name和div是char数组(文本内容),但整个对象的存储会包含内存对齐的填充字节,加上int类型的二进制值,记事本会把所有这些字节强行当成ASCII/UTF-8字符解析,自然就显示成乱码了。
怎么正确处理这个文件?
根据你的需求,有两种可行的方案:
方案1:写程序读取二进制文件(推荐,因为你本来用的是二进制写入)
既然是用二进制格式存储的对象,就得用对应的二进制读取逻辑来解析。给你补全读取的代码:
#include<iostream> #include<fstream> using namespace std; class Student { int rollno; char name[20]; char div[20]; public: void accept() { cout<<"enter rollno"<<endl; cin>>rollno; cout<<"Enter name"<<endl; cin>>name; cout<<"Enter div"<<endl; cin>>div; } void write_rec() { ofstream f; f.open("Student.dat",ios::binary|ios::app); Student s; s.accept(); f.write(reinterpret_cast<char*>(&s), sizeof(s)); f.close(); } // 新增读取函数 void read_rec() { ifstream f; f.open("Student.dat", ios::binary); Student s; // 循环读取每个对象,直到文件末尾 while(f.read(reinterpret_cast<char*>(&s), sizeof(s))) { cout << "Roll No: " << s.rollno << endl; cout << "Name: " << s.name << endl; cout << "Division: " << s.div << endl; cout << "-------------------------" << endl; } f.close(); } }; int main() { Student s; // 写入数据(可以调用多次) s.write_rec(); // 读取并打印数据 s.read_rec(); return 0; }
运行这个程序,就能正确输出你写入的学生信息,因为它是按照Student对象的内存结构来读取解析的。
方案2:生成纯文本文件(适合记事本直接查看)
如果你本来就想生成记事本能正常打开的文件,别用二进制模式,改成文本模式写入,把每个字段按纯文本格式输出:
void write_rec_text() { ofstream f("Student.txt"); // 默认是文本模式,不用加ios::binary Student s; s.accept(); // 按文本格式写入,字段用空格分隔 f << s.rollno << " " << s.name << " " << s.div << endl; f.close(); }
这样生成的Student.txt是纯文本文件,用记事本打开就能直接看到清晰的内容。
额外小提示
- 二进制文件的优势是读写效率高,适合存储复杂的自定义对象,但不适合人类直接查看,只有对应的程序能正确解析它。
- 如果你非要“看”二进制文件的内容,可以用十六进制编辑器(比如HxD、WinHex),它们会把二进制数据转成十六进制值和对应的ASCII字符,你能看到
name和div的文本部分,以及rollno的十六进制表示。
内容的提问来源于stack exchange,提问作者Abhishek Indapure
相关产品推荐
相关产品推荐

