将一个类通过二进制的方式写入到文件中,为什么类里面的字符串以数组形式才是对的?

如果代码是这样:

#include <iostream>
#include<fstream>
using namespace std;
//姓名和成绩以二进制方式保存,键盘输入
class Student {
public:
    **char *s=new char[20]; **
    int age; 
};
int main()
{
    Student    s;
    ofstream file1("c://file//dump.mp3", ios::out | ios::binary);
    while (cin>>s.s>>s.age) {
        cout << s.s << endl;
        file1.write((const char*)&s, sizeof(s));
    }
    file1.close();
    ifstream file2("c://file//dump.mp3", ios::in | ios::binary);
    while (file2.read((char*)&s, sizeof(s)) ){
        cout << s.s << " " << s.age << endl;
    }
    file2.close();
}

输入 Tom 13 和Jake 18后最后的输出结果是如下:
image.png
最后两行名字都是Jake。
但是如果将字符串改成char s[20];

#include <iostream>
#include<fstream>
using namespace std;
//姓名和成绩以二进制方式保存,键盘输入
class Student {
public:
    **char s[20];**
    int age; 
};
int main()
{
    Student    s;
    ofstream file1("c://file//dump.mp3", ios::out | ios::binary);
    while (cin>>s.s>>s.age) {
        cout << s.s << endl;
        file1.write((const char*)&s, sizeof(s));
    }
    file1.close();
    ifstream file2("c://file//dump.mp3", ios::in | ios::binary);
    while (file2.read((char*)&s, sizeof(s)) ){
        cout << s.s << " " << s.age << endl;
    }
    file2.close();
}

最后结果:
image.png
是正确的
请问为什么一定要是数组的方式才是对的?

阅读 2.3k
2 个回答
class Student { 
  public:
    char s[20]; 
    int age; 
};

sizeof(Student)

class Student { 
  public:
    char *s; 
    int age; 
};

sizeof(Student)

自己去验证

1,纠正个概念问题,
char s[20] 和 char* s =new char[20]
都是数组。
区别是前者在栈区,后者在堆区。只是占内存的位置不同。

2,你的代码有很多错误的用法,C++就是这样,过于自由,虽然逻辑上错了,但是编译器没有提示你这样不安全。
错误很多,对于你提出的问题,我只说重点。

为什么char* s =new char[20]打印出来错误的结果?
因为你把类指针强转类型直接写入文件,因为写入长度8字节,实际上你写入了错误的s。因为new出来的空间,跟你这个s对象,是分开放的。
你写入的s的部分,对于字符串来讲
**全是错的**
你只把指针写进去了,正确的字符串,没有写入到文件中。
那为什么还能打印出最后一次输入的字符串呢?
你打印的并不是写入文件的错误字符,而是你之前保存在对象s中的字符串,
也就是最后一次输入的字符串,一直在内存中,并不是你从文件里读出来的。

也就是说,你输入
TOM 13 JOKE 18,
最后打印出来 
JOKE 13 JOKE 18,这个JOKE是你最后一次输入到内存中的JOKE,不是文件里读出来的,文件里对应位置是错误的内容,用字符串格式根本没有成功读取。
如果你不信,你把这个程序分成两段,先写入,再用用另一个程序去读取,你会发现读字符串就错了。
一个JOKE都没有。

最后,为什么用char s[20]是正确的,因为这个在栈区,你强转后s的指向和sizeof计算的长度都正确。
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题