为什么使用fstream读写二进制文件没法正常读写?
可能的问题一
如果没有关闭ofstream就新建一个ifstream,此时无法正常读取出数据。
要注意及时关闭文件流,否则无法正常读写
比如下面的代码:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
using namespace std;
class Maker {
public:
Maker() = default;
Maker(const char* name,int age) {
strcpy(this->name, name);
this->age = age;
}
void printM() {
cout << this->name << " " << this->age << endl;
}
public:
char name[64];
int age;
};
int main()
{
Maker m1("小林", 20);
Maker m2("布林", 22);
ofstream ofs;
ofs.open("test.dat", ios::out |ios::binary );
if (!ofs.is_open()) {
cout << "打开文件失败" << endl;
}
ofs.write((const char *)&m1, sizeof(Maker));
ofs.write((const char *)&m2, sizeof(Maker));
ofs.close();
ifstream ifs;
ifs.open("test.dat", ios::in | ios::binary);
if (!ifs.is_open()) {
cout << "dakaiwenjianshibai" << endl;
}
Maker m3;
Maker m4;
ifs.read((char*)&m3, sizeof(Maker));
ifs.read((char*)&m4, sizeof(Maker));
m3.printM();
m4.printM();
system("pause");
return 0;
}
可能的问题二
文件读写时要注意不要使用string类型的数据
string类中有一个成员指针 char * ,该指针指向存储字符串的空间,
当我们把string类的数据存储到文件中再读出来时,不能保证指针有效。
比如上面的例子,单纯将char数组该成string之后:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class Maker {
public:
Maker() = default;
Maker(string name,int age) {
this->name = name;
this->age = age;
}
void printM() {
cout << " " << this->age << this->name<< endl;
}
public:
string name;
int age;
};
int main()
{
Maker m1("小林", 20);
Maker m2("布林", 22);
ofstream ofs;
ofs.open("test.dat", ios::out |ios::binary );
if (!ofs.is_open()) {
cout << "打开文件失败" << endl;
}
ofs.write((const char *)&m1, sizeof(Maker));
ofs.write((const char *)&m2, sizeof(Maker));
ofs.close();
ifstream ifs;
ifs.open("test.dat", ios::in | ios::binary);
if (!ifs.is_open()) {
cout << "dakaiwenjianshibai" << endl;
}
Maker m3;
Maker m4;
ifs.read((char*)&m3, sizeof(Maker));
ifs.read((char*)&m4, sizeof(Maker));
m3.printM();
m4.printM();
system("pause");
return 0;
}
无法正常运行,会崩掉。
排除发现是Maker调用默认析构函数时,string类的析构函数出了问题,就是因为上面说的,无法保证指针有效。
另外应该注意:
string 开辟的空间如果大于 16 个字节,就在堆区,否则在栈区:
|