Storing/Reading vectors to a file

Hi, I'm currently writing a program to store and read vectors to a file. These are my instructions:

Save Vehicles - This should save all vehicles currently stored in the vector to a file(the name and location can be hardcoded, but should preferably be input by the user)

Load Vehicles - This should replace the vehicles currently in the vector by those stored in a file (but should preferably be input by the user)

However, I do not understand how to only store/read the objects into a file and NOT overwrite the data after a file has been saved. For example, I create two vehicle objects, then save it to a file, create a new vehicle object and then load the file. However, the file loads three vehicles, it should not include the third. This is the only section, I am struggling to grasp. Any help would be greatly appreciated.

Here is my code:

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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
// Define read/write functions to a file
void saveVector(vector<Vehicle *>);
void loadVector(vector<Vehicle *>);

// Main Function
int main()
{
	// Declare variables and STL vector
	bool cont = true;
	vector <Vehicle *> vehicles;
	
	// While loop to check whether program should run
	while (cont)
	{
		// Loop variables
		int optionSelect;
		int createSelect;

		// Ask the user to select a type of vehicle
		cout << "-      Main Menu      -" << endl << endl;
		cout << "------------" << endl;
		cout << "0: Create " << endl;
		cout << "1: Save" << endl;
		cout << "2: Load" << endl;
		cout << "3: Print" << endl;
		cout << "4: Quit" << endl;
		cout << "------------" << endl << endl;

		// Read user selection
		cout << "Selection: ";
		cin >> optionSelect;
		cout << endl;

		// Switch statement to create new vehicle objects
		switch (optionSelect)
		{
			case 0:
				{
					break;
				}
			case 1: 
				{
					// Call save function
					saveVector(vehicles);
					break;
				}
			case 2:
				{
					// Call load function
					loadVector(vehicles);
					break;
				}
			case 3:
				{
					// Display objects
					for (size_t i = 0; i < vehicles.size(); i++)
					{
						vehicles[i]->display();
					}
					break;
				}
			case 4: 
				{
					// Delete objects
					for (size_t i = 0; i < vehicles.size(); i++)
					{
						delete vehicles[i];
					}

					// Ensure vector has no elements by using clear function
					vehicles.clear();

					// Quit the program
					cont = false;
					break;
				}
			default:
				{
					break;
				}
		}

		if (optionSelect == 0)
		{
			cout << "Please select an option: " << endl;
			cout << "------------" << endl;
			cout << "0: Bicycle" << endl;
			cout << "1: Car" << endl;
			cout << "2: Motorcycle" << endl;
			cout << "3: Motorhome" << endl;
			cout << "4: Train" << endl;
			cout << "5: Van" << endl;
			cout << "------------" << endl << endl;

			// Retrieve user input
			cout << "Selection: ";
			cin >> createSelect;
			cout << endl;

			switch (createSelect)
			{
				case 0:
					{
						vehicles.push_back(new Bicycle("Bicycle", "", "", 0, 0, 0));
						vehicles.back()->populate();
						break;
					}
				case 1:
					{
						vehicles.push_back(new Car("Car", "", "", 0, "", "", 0, "", 0));
						vehicles.back()->populate();
						break;
					}
				case 2:
					{
						vehicles.push_back(new Motorcycle("Motorcycle", "", "", 0, "", "", 0, 0, 0));
						vehicles.back()->populate();
						break;
					}
				case 3:
					{
						vehicles.push_back(new Motorhome("Motorhome", "", "", 0, "", "", 0, 0, 0));
						vehicles.back()->populate();
						break;
					}
				case 4:
					{
						vehicles.push_back(new Train("Train", "", "", 0, "", "", 0, 0, 0));
						vehicles.back()->populate();
						break;
					}
				case 5:
					{
						vehicles.push_back(new Van("Van", "", "", 0, "", "", 0, 0, 0));
						vehicles.back()->populate();
						break;
					}
				default:
					{
						break;
					}
			}
		}
	}	
	return 0;
}

// Function that provides the ability to write to a file
void saveVector(vector <Vehicle *> vehicles)
{
	string fileName;

	// Ask the user to provide a file name
	cout << "Please provide a file name: ";
	cin >> fileName;
	cout << endl;

	ofstream newFile(fileName);
	newFile.open(fileName.c_str(), ios::trunc);

	if (newFile.is_open())
	{
		// For each element in the vector
		for (size_t i = 0; i < vehicles.size(); i++)
		{
			// Store each vehicle element in the file
			newFile << vehicles[i] << endl;
			
		}

		newFile.close();
	}
	else
	{
		cout << "Unable to create file" << endl << endl;
	}
}

// Function that provides the ability to read a file
void loadVector(vector <Vehicle *> vehicles)
{
	// Declare file instance
	string fileName;

	// Ask the user to enter a filename to load
	cout << "Enter a current saved filename to read: ";
	cin >> fileName;
	cout << endl;

	ifstream newFile (fileName.c_str());
	
	// Produce error checking for input loading
	if (newFile.is_open())
	{
		cout << "File opened successfully" << endl << endl;

		if (newFile.good())
		{
			// For each element in the vector
			for (size_t i = 0; i < vehicles.size(); i++)
			{
				// Call display function to print content in file
				//vehicles[i]->display();
			}
		}
		newFile.close();
	}
	else
	{
		// Prompt user with error message
		cout << "Incorrect file name, file opening failed." << endl << endl;
	}
}
I do not understand how to only store/read the objects into a file and NOT overwrite the data after a file has been saved.
ios::app :
All output operations are performed at the end of the file, appending the content to the current content of the file. This flag can only be used in streams open for output-only operations.

Source:
http://www.cplusplus.com/doc/tutorial/files/

Edit:
When you load 2 vehicles and you get three, is the last vehicle blank( populated with blank data )?
Last edited on
Okay, assume you have an interface as above allowing you to create a vehicle object and store these into a vector. I am being asked to save/load these vehicle objects to a file.

I create two vehicles and save them to a file, then create a new vehicle (that makes 3 objects), and then if I load the file (that should only display 2 objects)
but it displays all three in the vector.

My display function "displays" all objects in the vector, but I am stuck on only storing/reading the objects in the file. So the end result, should be saving/loading two vehicle objects.

I hope this is more understandable. :)
Why don't you just overload operator>> so that you can read it in a similar way to how you wrote it.
newFile >> vehicles[i];
@Peter87

My lecturer said something about overloading operators, but I have no idea what he was talking about. Through one ear and out the other :(
I thought you had overloaded operator<< for 167 to work but I see now that you are just writing the pointer value to file. Instead, you need to write the data members of the Vehicle object. When reading the object you read the data members from the file in the same order you wrote them. If you do this using operator overloading, another function, or do everything in the same loop is up to you. You also need to handle the case when the number of vehicles in the vector is different from the number of vehicles in the file.
I really appreciate your input Peter. But could you please give me an example of doing this please. I'm really in a big hole unfortunately.

Last edited on
You can read and write to file the same way you write and read from the console, but instead of using std::cin you use an object of type std::ifstream and instead of std::cout you use an object of type std::ofstream.

I don't know what data a Vehicle contain but say it contain two int variables, milage and seats.
file << vehicles[i]->milage << ' ' << vehicles[i]->seats << endl;

And to read them you just read them in the same order.
file >> vehicles[i]->milage >> vehicles[i]->seats;
Topic archived. No new replies allowed.