我试图学习如何破解文件格式,所以我从一个简单的例子开始:How to read / write a struct in Binary Files?
#include <fstream>
#include <iostream>
#include <vector>
#include <string.h>
using namespace std;
typedef struct student
{
char name[10];
double age;
vector<int> grades;
}student_t;
void readBinaryFile(string filename)
{
ifstream input_file(filename, ios::binary);
student_t master[3];
input_file.read((char*)&master, sizeof(master));
for (size_t idx = 0; idx < 3; idx++)
{
// If you wanted to search for specific records,
// you should do it here! if (idx == 2) ...
cout << "Record #" << idx << endl;
//cout << "Capacity: " << master[idx].grades.capacity() << endl;
cout << "Name: " << master[idx].name << endl;
cout << "Age: " << master[idx].age << endl;
cout << "Grades: " << endl;
for (size_t i = 0; i < master[idx].grades.size(); i++)
cout << master[idx].grades[i] << " ";
cout << endl << endl;
}
input_file.close();
}
int main()
{
student_t apprentice[3];
strcpy(apprentice[0].name, "john");
apprentice[0].age = 21;
apprentice[1].grades.push_back(1);
apprentice[1].grades.push_back(2);
apprentice[1].grades.push_back(3);
strcpy(apprentice[1].name, "jerry");
apprentice[1].age = 22;
apprentice[0].grades.push_back(4);
apprentice[0].grades.push_back(5);
apprentice[0].grades.push_back(6);
strcpy(apprentice[2].name, "jimmy");
apprentice[2].age = 24;
apprentice[2].grades.push_back(7);
apprentice[2].grades.push_back(8);
apprentice[2].grades.push_back(9);
string filename = "students2.data";
// Serializing struct to student.data
ofstream output_file(filename, ios::binary);
output_file.write((char*)&apprentice, sizeof(apprentice));
output_file.close();
// Reading from it
readBinaryFile(filename);
system("pause");
return 0;
}
我可以编写文件并正确阅读,当我在十六进制编辑器中打开它时,我明白了:
6a 6f 68 6e 00 cc cc cc cc cc cc cc cc cc cc cc
00 00 00 00 00 00 35 40 40 59 84 00 80 cf 84 00
8c cf 84 00 8c cf 84 00 6a 65 72 72 79 00 cc cc
cc cc cc cc cc cc cc cc 00 00 00 00 00 00 36 40
50 85 84 00 60 d0 84 00 6c d0 84 00 6c d0 84 00
6a 69 6d 6d 79 00 cc cc cc cc cc cc cc cc cc cc
00 00 00 00 00 00 38 40 50 79 84 00 b8 cf 84 00
c4 cf 84 00 c4 cf 84 00
我可以清楚地找到姓名(6a 6f 68 6e 00 cc cc cc cc cc)和年龄(00 00 00 00 00 00 35 40),但我在找到成绩值时遇到了很多麻烦。我想通过制作具有不同值的第二个文件我可以找到差异,但我找到了一些我不理解的东西。通过将第一个学生改为:
strcpy(apprentice[0].name, "john");
apprentice[0].age = 21;
apprentice[1].grades.push_back(1);
apprentice[1].grades.push_back(2);
apprentice[1].grades.push_back(3);
apprentice[1].grades.push_back(4);
apprentice[1].grades.push_back(5);
apprentice[1].grades.push_back(6);
我希望得到一个更大的文件,但它的大小不会改变:
6a 6f 68 6e 00 cc cc cc cc cc cc cc cc cc cc cc
00 00 00 00 00 00 35 40 40 59 8e 00 48 cf 8e 00
54 cf 8e 00 54 cf 8e 00 6a 65 72 72 79 00 cc cc
cc cc cc cc cc cc cc cc 00 00 00 00 00 00 36 40
50 85 8e 00 88 79 8e 00 ac 79 8e 00 ac 79 8e 00
6a 69 6d 6d 79 00 cc cc cc cc cc cc cc cc cc cc
00 00 00 00 00 00 38 40 50 79 8e 00 98 d0 8e 00
a4 d0 8e 00 a4 d0 8e 00
怎么可能?我甚至尝试使用60多个元素的矢量,文件仍然保持相同的大小...任何帮助将不胜感激!
编辑:正如tux3指出的那样,我实际上并没有将我的矢量保存为二进制文件。我应该更加关注我复制的代码,不好。答案 0 :(得分:5)
output_file.write((char *)&amp; apprentice,sizeof(apprentice));
这不符合您的想法。 std::vector
将其数据放在免费商店中,而不是像数组一样放在对象本身中。
所以在这里你只是编写矢量的元数据(它的大小,容量,指向数据的指针......),而不是数据本身。