using vector of structs and passing functions

I'm working on a project and I've hit a few roadblocks so. I'm supposed to write a program the user types in a part number, it will come back with a report on the console like,

**There are 11 of Part Number P-33195 in inventory. It is a class C part. The cost is $24.00. The value of that inventory is $264.00. **

but if that part number isn't on file it should tell the user that and it has to be able to insert into the list. The program should then continue on asking for more part numbers, until the user says they don't want any more. (All this info is stored in a part file)
After the user says they dont want to search for any more part numbers, a report should be printed telling how many searches, how many were successful and how many new part numbers were added. And, it should write the file out again, so the additions are saved.

This is what I have so far

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
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
  #include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <vector>
using namespace std;

ofstream fout("NewPartsList.txt");



struct programParts
{
	string partNumber;
	char partClass;
	int partOHB;
	double partCost;
}P2;

// Function Prototypes

// Fills Vectors
bool getData(vector <programParts> & V);

// Does a binary search
int binSearch(const vector <programParts> &V, string key, int min, int max);

// Asks user for a part number to search for
string getTarget(vector <programParts> &V);

// Gets remaining info to add a part number
void getMoreData(vector <programParts> &V);

// Inserts part number data into vectors into the proper location
// See book for information on how to write this
void insertData(vector <programParts>& V, programParts toAdd);

// Displays info on part number
void display(const vector <programParts> &V);

// sorts vectors (Calls swapper) 
void sort(vector <programParts> & V);

// Prints search stats
void printStats(int searches, int good, int bad);

// Writes out file when program ends, so additions are saved to file
void putData(const vector <programParts> & V);

// Templated swap function – Swaps two items in a vector of any type
template <class CType>
void swapper(CType& a, CType & b)
{
	CType temp;
	temp = a;
	a = b;
	b = temp;
}

int main()
{
	vector <programParts> V;
	char choice;
	char choiceAgain;
	bool read;
	read = getData(V);
	int good = 0;
	int bad = 0;
	int searches = 0;

	if (read == true)
	{
		display(V);
		cout << "Would you like to do another search? (Y or N) " << endl;
		cin >> choice;
		if (choice == 'Y')
		{
			getMoreData(V);
			cout << "Would you like to do another search?" << endl;
			cin >> choiceAgain;
			if (choiceAgain == 'Y')
			{
				printStats(searches, good, bad);

			}
			
			
		}
		else
			cout << "Goodbye!" << endl;
		
	}
	else
		cout << endl;





}

bool getData(vector <programParts> & V)
{

	bool no = false;
	bool ok = true;
	programParts programIn;
	ifstream inputFile;
	inputFile.open("parts.txt");
	if (inputFile.fail())
	{
		return no;
	}
	else
	{
		while (inputFile >> programIn.partNumber >> programIn.partClass >> programIn.partOHB >> programIn.partCost)
		{
			V.push_back(programIn);
		}
		inputFile.close();
	}
	return ok;
}

int binSearch(const vector <programParts> &V, string key, int min, int max)
{
	bool found = false;
	int middle, position = -1;
	while (!found && min <= max)
	{
		middle = (min + max) / 2;

		if (V[middle].partNumber == key)
		{
			found = true;
			position = middle;
		}
		else if (V[middle].partNumber > key)
		{
			max = middle - 1;
		}
		else
		{
			min = middle + 1;
		}
	}
	return position;
}

string getTarget(vector <programParts> &V)
{
	string partNumber;
	cout << "What part number would you like to look for?" << endl;
	cin >> partNumber;
	return partNumber;

}

void insertData(vector <programParts>& V, programParts toAdd)
{
	int max = V.size();
	int min = 0;
	int middle, position = 1;
	bool found = false;
	while (!found && min <= max)
	{
		middle = (min + max) / 2;

		if (V[middle].partNumber == P2.partNumber)
		{
			found = true;
			position = middle;
		}
		else if (V[middle].partNumber > P2.partNumber)
		{
			max = middle - 1;
		}
		else
		{
			min = middle + 1;
		}
		if (position == -1)
		{
			if (V[middle].partNumber > P2.partNumber)
			{
				position = middle;
			}
			else
			{
				position = middle + 1;
			}
		}
		else
		{
			position = middle;
		}
		V.insert(V.begin() + position, P2);
	}

}


void sort(vector <programParts> & V)
{
	bool flag = true;
	int i, letter = V.size();
	int x = letter;
	while (flag || (x > 1))
	{
		flag = false;
		x = (x + 1) / 2;

		for (int i = 0; i < (letter - x); i++)
		{

			if (V[i + x].partNumber < V[i].partNumber)
			{
				swapper(V[i], V[i + x]);
				flag = true;
			}
		}
	}
}

void putData(const vector <programParts> & V)
{

	for (int i = 0; i < V.size(); i++)
	{
		fout << V[i].partNumber << " " << V[i].partClass << " " << V[i].partOHB << " " << V[i].partCost;
	}
	fout.close();
}

void getMoreData(vector <programParts> &V)
{
	string partNumber;
	char choice;
	char anotherChoice;
	char choiceAgain;
	char choiceClass;
	int choiceOHB;
	double choiceCost;
	vector <programParts> A;
	int good = 0;
	int bad = 0;
	int searches;

	cout << "What part number would you like to look for?" << endl;
	cin >> partNumber;

	cout << "Add this part?" << endl;
	cin >> choice;

	if (choice == 'Y')
	{
		cout << "What class is this part number in?" << endl;
		cin >> choiceClass;


		cout << "What is the on hand balance of this part?" << endl;
		cin >> choiceOHB;


		cout << "What is the cost of this part?" << endl;
		cin >> choiceCost;

		fout << partNumber << " " << choiceClass << " " << choiceOHB << " " << choiceCost << endl;

		cout << "Would you like to do another search (Y or N)" << endl;
		cin >> anotherChoice;

		if (anotherChoice == 'Y')
		{
			cout << "What part number would you like to look for?" << endl;
			cin >> partNumber;
			cout << "There are" << " " << choiceOHB << " " << "of part number" << " " << partNumber << " " << "in the inventory." << " " << "It is a class" << " " << choiceClass << " " << "part." << endl;
			cout << "The cost is" << " " << "$" << choiceCost << "." << "The value of that inventory is" << endl;
		}
		else
			cout << endl;


	}
}

void display(const vector <programParts> &V)
{
	int max = V.size();
	int min = 0;
	vector <programParts> A;
	string key = getTarget(A);
	int i = binSearch(V, key, min, max);
	int specificOHB;
	char specificClass;
	string specificNumber;
	double specificCost;
	double specificCostInventory = 0;


	specificClass = V[i].partClass;
	specificCost = V[i].partCost;
	specificOHB = V[i].partOHB;
	specificNumber = V[i].partNumber;

	for (int i = 0; i < V.size(); i++)
	{
		specificCostInventory = V[i].partClass + V[i].partCost + specificCostInventory;
	}


	cout << "There are" << " " << specificOHB << " " << "of part number" << " " << key << " " << "in the inventory." << " " << "It is a class" << " " << specificClass << " " << "part." << endl;
	cout << "The cost is" << " " << "$" << specificCost << "." << "The value of that inventory is" << " " << "$" << specificCostInventory << endl;
}

void printStats(int searches, int good, int bad)
{
	cout << "There were 3 searches performed today." << endl;
	cout << "however many were succesfull" << " " << "of them were succesfull" << endl;
	cout << "however werent in the system" << " " << "of them were not in the system" << endl;
	cout << "The file is now updated" << endl;

}


Sample of parts.txt file
P-39457 A 16 102.14
P-11702 B 21 24.74
P-11754 B 27 15.23
P-12009 D 3 12.80
P-12131 A 48 24.17
P-12385 B 41 27.33
P-12652 E 18 28.33
P-12677 D 15 26.59
P-12746 A 6 111.57
P-12746 C 25 14.83
P-12797 D 18 29.07
P-12856 A 33 120.96
P-13192 C 65 76.98
P-13289 C 45 36.61
P-13682 D 14 25.56
P-13713 A 10 35.12
P-14175 B 41 9.21
P-14226 D 14 28.95
Thank you gunnerfunner but for this project i'm actually not supposed to use anything aside from
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <vector>

So I made some more changes, but now the issue arises whenever I try to call the typed in part number, my program just crashes and I'm not sure why because its being outputted into the NewPartsList text

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
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296

#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <vector>
using namespace std;

ofstream fout("NewPartsList.txt");



struct programParts
{
	string partNumber;
	char partClass;
	int partOHB;
	double partCost;
}P2;

// Function Prototypes

// Fills Vectors
bool getData(vector <programParts> & V);

// Does a binary search
int binSearch(const vector <programParts> &V, string key, int min, int max);

// Asks user for a part number to search for
string getTarget(vector <programParts> &V);

// Gets remaining info to add a part number
void getMoreData(vector <programParts> &V);

// Inserts part number data into vectors into the proper location
// See book for information on how to write this
void insertData(vector <programParts>& V, programParts toAdd);

// Displays info on part number
void display(const vector <programParts> &V);

// sorts vectors (Calls swapper) 
void sort(vector <programParts> & V);

// Prints search stats
void printStats(int searches, int good, int bad);

// Writes out file when program ends, so additions are saved to file
void putData(const vector <programParts> & V);

// Templated swap function – Swaps two items in a vector of any type
template <class CType>
void swapper(CType& a, CType & b)
{
	CType temp;
	temp = a;
	a = b;
	b = temp;
}

int main()
{
	vector <programParts> V;
	char choice;
	char choiceAgain;
	bool read;
	bool readAgain;
	read = getData(V);

	if (read == true)
	{
		do
		{

			display(V);
			cout << "Would you like to do another search (Y or N)" << endl;
			cin >> choice;
			getMoreData(V);
			putData(V);
			
		} while (choice != 'Y');
		
	}
	display(V);
	
}

bool getData(vector <programParts> & V)
{

	bool no = false;
	bool ok = true;
	programParts programIn;
	ifstream inputFile;
	inputFile.open("parts.txt");
	if (inputFile.fail())
	{
		return no;
	}
	else
	{
		while (inputFile >> programIn.partNumber >> programIn.partClass >> programIn.partOHB >> programIn.partCost)
		{
			V.push_back(programIn);
		}
		inputFile.close();
	}
	return ok;
}


int binSearch(const vector <programParts> &V, string key, int min, int max)
{
	bool found = false;
	int middle, position = -1;
	while (!found && min <= max)
	{
		middle = (min + max) / 2;

		if (V[middle].partNumber == key)
		{
			found = true;
			position = middle;
		}
		else if (V[middle].partNumber > key)
		{
			max = middle - 1;
		}
		else
		{
			min = middle + 1;
		}
	}
	return position;
}

string getTarget(vector <programParts> &V)
{
	string partNumber;
	cout << "What part number would you like to look for?" << endl;
	cin >> partNumber;
	return partNumber;

}

void insertData(vector <programParts>& V, programParts toAdd)
{
	int max = V.size();
	int min = 0;
	int middle, position = 1;
	bool found = false;
	while (!found && min <= max)
	{
		middle = (min + max) / 2;

		if (V[middle].partNumber == P2.partNumber)
		{
			found = true;
			position = middle;
		}
		else if (V[middle].partNumber > P2.partNumber)
		{
			max = middle - 1;
		}
		else
		{
			min = middle + 1;
		}
		if (position == -1)
		{
			if (V[middle].partNumber > P2.partNumber)
			{
				position = middle;
			}
			else
			{
				position = middle + 1;
			}
		}
		else
		{
			position = middle;
		}
		V.insert(V.begin() + position, P2);
	}

}


void sort(vector <programParts> & V)
{
	bool flag = true;
	int i, letter = V.size();
	int x = letter;
	while (flag || (x > 1))
	{
		flag = false;
		x = (x + 1) / 2;

		for (int i = 0; i < (letter - x); i++)
		{

			if (V[i + x].partNumber < V[i].partNumber)
			{
				swapper(V[i], V[i + x]);
				flag = true;
			}
		}
	}
}

void putData(const vector <programParts> & V)
{

	for (int i = 0; i < V.size(); i++)
	{
		fout << V[i].partNumber << " " << V[i].partClass << " " << V[i].partOHB << " " << V[i].partCost << endl;
	}
	fout.close();
}

void getMoreData(vector <programParts> &V)
{
	string partNumber;
	char choice;
	char anotherChoice;
	char choiceAgain;
	char choiceClass;
	int choiceOHB;
	double choiceCost;
	

	cout << "What part number would you like to look for?" << endl;
	cin >> partNumber;

	cout << "Add this part?" << endl;
	cin >> choice;

	if (choice == 'Y')
	{
		cout << "What class is this part number in?" << endl;
		cin >> choiceClass;


		cout << "What is the on hand balance of this part?" << endl;
		cin >> choiceOHB;


		cout << "What is the cost of this part?" << endl;
		cin >> choiceCost;

		fout << partNumber << " " << choiceClass << " " << choiceOHB << " " << choiceCost << endl;
	}
}

void display(const vector <programParts> &V)
{
	int max = V.size();
	int min = 0;
	vector <programParts> A;
	string key = getTarget(A);
	int i = binSearch(V, key, min, max);
	int specificOHB;
	char specificClass;
	string specificNumber;
	double specificCost;
	double specificCostInventory = 0;
	
	specificClass = V[i].partClass;
	specificCost = V[i].partCost;
	specificOHB = V[i].partOHB;
	specificNumber = V[i].partNumber;

	for (int i = 0; i < V.size(); i++)
	{
		specificCostInventory = V[i].partClass + V[i].partCost + specificCostInventory;
	}

	cout << "There are" << " " << specificOHB << " " << "of part number" << " " << key << " " << "in the inventory." << " " << "It is a class" << " " << specificClass << " " << "part." << endl;
	cout << "The cost is" << " " << "$" << specificCost << "." << "The value of that inventory is" << " " << "$" << specificCostInventory << endl;
	

}


void printStats(int searches, int good, int bad)
{
	cout << "There were 3 searches performed today." << endl;
	cout << "however many were succesfull" << " " << "of them were succesfull" << endl;
	cout << "however werent in the system" << " " << "of them were not in the system" << endl;
	cout << "The file is now updated" << endl;

}



2 operator overloads for stream insertion: (a) for printing successful searches to console with all it's details and (b) for writing new program parts to and printing existing list to console before program ends
there are comments throughout and google any of the functions if unfamiliar and, of course, you're welcome to come back here with any remaining queries:
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
#include <iostream>
#include <vector>
#include <algorithm>
#include <fstream>
#include <sstream>
#include <string>
#include <limits>
#include <utility>

struct programParts
{
    std::string m_partNumber;
    char m_partClass;
    unsigned int m_partOHB;
    double m_partCost;

    programParts(const std::string& partNumber, const char partClass, const unsigned int partOHB, const double partCost)
        : m_partNumber(partNumber), m_partClass(partClass), m_partOHB(partOHB), m_partCost(partCost){}
};

std::ostream& operator << (std::ostream& os, const programParts& p)
//operator overload for printing succesful searches
{
    os << "There are " << p.m_partOHB << " of Part Number " << p.m_partNumber << " in inventory. It is a class "
        << p.m_partClass << " part. The cost is $" << p.m_partCost << ". The value of that inventory is $"
        << p.m_partOHB * p.m_partCost << ". \n";
    return os;
}
std::ostream& operator <<= (std::ostream & os, const programParts& p)
//operator overload for printing unsuccessful searches to file and final list to console
{
    os << p.m_partNumber << " " << p.m_partClass << " " << p.m_partOHB << " " << p.m_partCost << "\n";
    return os;
}
int main()
{
    std::vector<programParts> parts{};
    std::ifstream programFile{"D:\\test.txt"};

    if (programFile)//read the existing file once per program right at the start
    {
        std::string line{};
        while(getline(programFile, line))
        {
            std::istringstream stream{line};
            std::string partNumber{}; char partClass{};
            unsigned int partOHB{}; double partCost{};
            stream >> partNumber >> partClass >> partOHB >> partCost;
            if(programFile) parts.emplace_back(programParts{partNumber, partClass, partOHB, partCost});
        }
    }
    bool fQuit{false};
    size_t numSearch{};
    size_t partsAdd{};

    while(!fQuit)
    {
        std::cout << "Select your option: 1. Enter part number \t2. Quit \n";
        int choice{};
        std::cin >>  choice;//input validation here and throughout recommended
        std::cin.clear();//to remove the newline character from input stream
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

        switch (choice)
        {
            case 1:
            {
                ++numSearch;
                std::string partNumber{};
                getline(std::cin, partNumber);
                auto itr = std::find_if(parts.cbegin(), parts.cend(), [&partNumber](const programParts& p)
                    {return p.m_partNumber == partNumber;});
                if (itr != parts.cend())
                {
                    std::cout << *itr;//usees the first stream insertion overload
                }
                else
                {
                    ++partsAdd;
                    std::cout << "This part does not exist in file, need its remaining details \n";
                    char partClass{}; unsigned int partOHB{}; double partCost{};
                    std::cout << "Enter part class: \n"; std::cin >> partClass;
                    std::cout << "Enter part OHB: \n"; std::cin >> partOHB;
                    std::cout << "Enter part cost: \n"; std::cin >> partCost;
                    std::cin.clear();
                    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
                    programParts p{programParts{partNumber, partClass, partOHB, partCost}};
                    std::ofstream programFile{"D:\\test.txt", std::ios_base::app};
                    //open in append move, local scoped variable
                    programFile <<= p;//second stream insertion overload
                    parts.push_back(std::move(p));//cheaper to move the part as it's no longer required
                }
            }
            break;
            case 2:
                std::cout << "There were " << numSearch << " searches \n";
                std::cout << "Successful searches: " << numSearch - partsAdd << "\n";
                std::cout << "Parts added: " << partsAdd << "\n";
                std::cout << "Current list of parts: \n";
                for (const auto& elem : parts)std::cout <<= elem;//second stream insertion overload
                fQuit = true;
                break;
            default:
                std::cout << "Incorrect choice, try again \n";
                break;
        }
    }
}
@gunnerfunner is there another way to be able to continue on with the project?
is there another way to be able to continue on with the project?

what exactly do you have in mind? usually with C++ there is always 'another way' and what are your constraints re using the program already suggested?
Last edited on
@gunnerfunner
With the suggested program I am not supposed to use any includes other than the ones that we were provided with which were
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <vector>
using namespace std;

And with that the way my code is running it continues to crash when the user has to look for a part number that was inputted
Last edited on
Topic archived. No new replies allowed.