c ++以二进制模式将文件读入对象失败但在stdin和文件中读取文本是可以的
c++ read file in binary mode into object failed but is ok in stdin and file read in text
这可能是个简单的问题...
stdin读取或text读取文件的方法已被证明是正确的。二进制读取出错。
这里我有一个名为class的Laptop和一个名为laptop.txt的文件,它是由后面的代码编写的。我已经重新加载了 >>
和 <<
using namespace std;
class Laptop
{
private:
string brand;
string cpu;
string ram;
string disk;
int reserve;
public:
Laptop() {}
Laptop(string aBrand, string aCpu, string aRam, string aDisk, int aReserve)
{
this->brand = aBrand;
this->cpu = aCpu;
this->ram = aRam;
this->disk = aDisk;
this->reserve = aReserve;
}
friend ostream &operator<<(ostream &os, const Laptop &laptop)
{
os << laptop.brand << " " << laptop.cpu
<< " " << laptop.ram << " " << laptop.disk << " " << laptop.reserve;
return os;
}
friend istream &operator>>(istream &is, Laptop &laptop)
{
is >> laptop.brand >> laptop.cpu >> laptop.ram >> laptop.disk >> laptop.reserve;
return is;
}
};
int main()
{
fstream file("laptop.txt", ios::out | ios::binary);
vector<Laptop> laptops;
Laptop aLaptop;
for (int i = 0; i < 5; i++)
{
cin >> aLaptop;
laptops.push_back(aLaptop);
}
for (vector<Laptop>::iterator i = laptops.begin(); i != laptops.end(); i++)
{
file.write((char *)(&i), sizeof(*i));
}
return 0;
}
但是在二进制读取中事情并不顺利。当我尝试将 aLaptop 推到矢量时,class Laptop 出现异常。我真的不知道为什么。太可怕了。
int main()
{
fstream file("laptop.txt", ios::in);
vector<Laptop> laptops;
Laptop aLaptop;
while (file.peek() != EOF)
{
file.read((char *)(&aLaptop), sizeof(aLaptop));
laptops.push_back(aLaptop);
}
return 0;
}
enter image description here
你有一个由四个字符串和一个 int 组成的 class,你将指向它的指针转换为字符指针,并尝试以二进制模式从文本文件中读取它。
一个字符串由一个长度和一个指针组成。指针指向包含字符的可变大小的内存块。 sizeof
returns 长度和指针的大小,但不是字符块。所以当你读取文件时,你得到的是长度和指针,但不是组成字符串的字符。因此指针指向垃圾。
正确的方法是:
- 如果您知道该字符串永远不会包含空字符,请读取字符,将它们附加到字符串,直到您得到一个空字符或文件结尾。
- 读取字符串的长度,然后读取那么多字符。如果你在这中间击中了文件末尾,抛出。
您还需要一个函数以相同的方式编写字符串。
从二进制文件中读取整数是可行的,只要该整数是以二进制形式写入的。为了便携性,最好以一致的字节顺序读写整数。
这可能是个简单的问题...
stdin读取或text读取文件的方法已被证明是正确的。二进制读取出错。
这里我有一个名为class的Laptop和一个名为laptop.txt的文件,它是由后面的代码编写的。我已经重新加载了 >>
和 <<
using namespace std;
class Laptop
{
private:
string brand;
string cpu;
string ram;
string disk;
int reserve;
public:
Laptop() {}
Laptop(string aBrand, string aCpu, string aRam, string aDisk, int aReserve)
{
this->brand = aBrand;
this->cpu = aCpu;
this->ram = aRam;
this->disk = aDisk;
this->reserve = aReserve;
}
friend ostream &operator<<(ostream &os, const Laptop &laptop)
{
os << laptop.brand << " " << laptop.cpu
<< " " << laptop.ram << " " << laptop.disk << " " << laptop.reserve;
return os;
}
friend istream &operator>>(istream &is, Laptop &laptop)
{
is >> laptop.brand >> laptop.cpu >> laptop.ram >> laptop.disk >> laptop.reserve;
return is;
}
};
int main()
{
fstream file("laptop.txt", ios::out | ios::binary);
vector<Laptop> laptops;
Laptop aLaptop;
for (int i = 0; i < 5; i++)
{
cin >> aLaptop;
laptops.push_back(aLaptop);
}
for (vector<Laptop>::iterator i = laptops.begin(); i != laptops.end(); i++)
{
file.write((char *)(&i), sizeof(*i));
}
return 0;
}
但是在二进制读取中事情并不顺利。当我尝试将 aLaptop 推到矢量时,class Laptop 出现异常。我真的不知道为什么。太可怕了。
int main()
{
fstream file("laptop.txt", ios::in);
vector<Laptop> laptops;
Laptop aLaptop;
while (file.peek() != EOF)
{
file.read((char *)(&aLaptop), sizeof(aLaptop));
laptops.push_back(aLaptop);
}
return 0;
}
enter image description here
你有一个由四个字符串和一个 int 组成的 class,你将指向它的指针转换为字符指针,并尝试以二进制模式从文本文件中读取它。
一个字符串由一个长度和一个指针组成。指针指向包含字符的可变大小的内存块。 sizeof
returns 长度和指针的大小,但不是字符块。所以当你读取文件时,你得到的是长度和指针,但不是组成字符串的字符。因此指针指向垃圾。
正确的方法是:
- 如果您知道该字符串永远不会包含空字符,请读取字符,将它们附加到字符串,直到您得到一个空字符或文件结尾。
- 读取字符串的长度,然后读取那么多字符。如果你在这中间击中了文件末尾,抛出。 您还需要一个函数以相同的方式编写字符串。
从二进制文件中读取整数是可行的,只要该整数是以二进制形式写入的。为了便携性,最好以一致的字节顺序读写整数。