So, my issue with your method is that the file by itself is somewhat useless, because how would you know the lengths of each string a priori? All the information you need should be self-contained WITHIN the file itself.
I'm actually decided not to do a null-terminated string approach, because I find that tedious that you have to read each character at a time for the duration of the string until you find a '\0'. It's certainly possible, though, and uses less data.
sizeof(nameCStr)
is the same as as saying
sizeof(char*)
which is a constant 8 bytes on 64-bit addressing machines.
Rule of thumb: The result sizeof is a compile-time constant in C++. Always treat it as such.
I think your method of map<string,vector<int> > is overly complicated.
(PS: I also see now why you're doing append, because you need to get the filesize). I used std::ate for that.
Here's my solution, let me know what questions you have about it.
The format of my file is
[age][name length][name][phone number length][phone number],
where:
- age is sizeof(int)
- name length is sizeof(std::string::size_type)
- name is variable
- phone number length is sizeof(std::string::size_type)
- phone number is variable
What I'm doing is writing the size of the string in advance, before the string itself, so that we know in advance what the length of the string is. No information is needed besides what's contained in the file itself.
Not tested when strings are 0 length, you might have to tweak it a bit for that.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
struct Person{
int age;
string name;
string phoneNumber;
};
void writeToFile(const vector<Person> &people){
ofstream out("binsecond.dat",ios::binary | ios::out);
if(!out.is_open()){
cout << "error opening file" << endl;
return;
}
for(size_t i = 0; i < people.size(); i++){
const Person& person = people.at(i);
int age = person.age;
const std::string& name = person.name;
const std::string& phone = person.phoneNumber;
std::string::size_type name_len = person.name.length();
std::string::size_type phone_len = person.phoneNumber.length();
//
// [age] [name length][name] [phone number length][phone number]
//
// age:
out.write((char*)&age, sizeof(age));
// name:
out.write((char*)&name_len, sizeof(name_len));
out.write(name.c_str(), name_len);
// phone:
out.write((char*)&phone_len, sizeof(phone_len));
out.write(phone.c_str(), phone_len);
}
}
void readFomFile(){
ifstream in("binsecond.dat", ios::ate | ios::binary);
if(!in.is_open()){
cout << "error opening file" << endl;
return;
}
int sizeOfFile = in.tellg();
in.seekg(0,ios::beg);
while (in.tellg() < sizeOfFile) {
// Reading age:
int age;
in.read((char*)&age,sizeof(age));
// Reading name length:
std::string::size_type name_len;
in.read((char*)&name_len, sizeof(name_len));
// Reading name:
std::string name;
name.resize(name_len);
in.read(&name[0], name_len);
// Reading phone length:
std::string::size_type phone_len;
in.read((char*)&phone_len, sizeof(phone_len));
// Reading phone:
std::string phone;
phone.resize(phone_len);
in.read(&phone[0], phone_len);
cout << "age: " << age << '\n';
cout << "name: " << name << '\n';
cout << "phone: " << phone << '\n';
cout << '\n';
// TODO: push_back to a vector or something if you want.
}
}
int main()
{
vector<Person> people;
Person adam;
adam.age = 22;
adam.name = "adam";
adam.phoneNumber = "0851512624";
Person mark;
mark.age = 21;
mark.name = "mark";
mark.phoneNumber = "0867778171";
Person james;
james.age = 28;
james.name = "james";
james.phoneNumber = "0876725262";
people.push_back(adam);
people.push_back(james);
people.push_back(mark);
std::cout << "\nWRITING...\n";
writeToFile(people);
std::cout << "\nREADING...\n";
readFomFile();
}
| |
WRITING...
READING...
age: 22
name: adam
phone: 0851512624
age: 28
name: james
phone: 0876725262
age: 21
name: mark
phone: 0867778171 |
Let me know what lines you want me to explain.