aboutsummaryrefslogtreecommitdiff
path: root/CST116F2021-Lab7/CST116F2021-Lab7.cpp
blob: aef1f640344ccb3d37f654ecab9db3936b57da8f (plain) (blame)
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
//Code by Jordan Harris-Toovy for OIT's CST116 lab 7, November 2021

#include <iostream>
#include <cstring>	//Needed for string datatype
#include <iomanip>
#include <sstream>	//Needed for getline
#include <limits>	//Needed for numeric_limits
using namespace std;


#define MAX_STRINGS 100
//Do not exceed 999; the output will become unevenly spaced

bool getInt(int&);
int menu(int&);
void addString(int, string[MAX_STRINGS]);
void printStrings(int, int, string[MAX_STRINGS]);
int stringSearch(int, string, string[MAX_STRINGS]);
int removeString(int, string[MAX_STRINGS]);

int main(void)
{
	string strArray[MAX_STRINGS]{}, searchString{};
	int occupiedPositions = 0, menuSelect = 1, searchTarget = 0;

	cout << "String playground MK1" << endl;

	while ((menuSelect >= 1) && (menuSelect <= 4))
	{
		menuSelect = menu(occupiedPositions);

		switch (menuSelect)
		{
		case (1):

			addString(occupiedPositions++, strArray);

			break;
		case (2):

			printStrings(0, occupiedPositions, strArray);

			break;
		case (3):

			if (occupiedPositions > 0)
			{
				cout << "Enter string to search: ";

				getline(cin >> ws, searchString);

				searchTarget = stringSearch(occupiedPositions, searchString, strArray);

				if (searchTarget < 0)
				{
					cout << "No match found" << endl;
				}
				else
				{
					cout << "The string \"" << searchString << "\" was found in srting \"" << strArray[searchTarget] << "\" which is in position " << searchTarget + 1 << endl;
				}
			}
			else
			{
				cout << "Cannot search: No stings stored" << endl;
			}


			break;
		case (4):

			occupiedPositions = removeString(occupiedPositions, strArray);

			break;
		}
	}

	return (0);
}

//Gets an input from the user, it not an int, returns false and sets input to 0
bool getInt(int& innum)
{
	bool valid = true;

	cin >> innum;

	if (!cin.good()) // Check if the input was an int
	{
		cin.clear(); //Clear failure condition flag 
		cin.ignore(numeric_limits<streamsize>::max(), '\n'); //Clear all non ints until next \n

		valid = false;
		innum = 0;
	}

	return valid;
}

//Display a menu and return a control value
int menu(int& pos)
{
	int menuSel = 0;
	bool valid_input = true;

	cout << "There are currently " << pos << " strings in the array." << endl
		<< "1) Add a string\n2) Print current strings\n3) Search for a substring\n4) Delete a string\n5) Exit" << endl;
	valid_input = getInt(menuSel);

	while ((menuSel < 1) || (menuSel > 5) || !valid_input) //Check if the entered value is one of the options, otherwise, ask again
	{
		cout << "Invalid entry, enter again: ";
		valid_input = getInt(menuSel);
	}

	return menuSel;
}

//Add a sting at the position sel into the array stringBase
void addString(int sel, string stringBase[MAX_STRINGS])
{
	cout << "Enter string: ";

	getline(cin >> ws, stringBase[sel]); //Discards all whitespace chars and reads in the input buffer until \n
}

//Prints srtings on their own lines from the stloc to edloc positions of the string array stringBase 
void printStrings(int stloc, int edloc, string stringBase[MAX_STRINGS])
{
	cout << endl;

	if (stloc == edloc) //Leave if stringBase is empty
	{
		cout << "No strings to display";
	}
	else
	{
		for (int idx = stloc; idx < edloc; idx++)
		{
			cout.setf(ios::left);
			cout << setw(3) << idx + 1 << " - " << stringBase[idx] << endl;
		}
	}

	cout << endl;
}

//Searches the first arrayDepth elements of stringBase for subString, returns -1 if not found, otherwise returns match index
int stringSearch(int arrayDepth, string subString, string stringBase[MAX_STRINGS])
{
	int strCheck = 0, offset = 0;

	for (int idx = 0; idx < arrayDepth; idx++) //Iterate through arrayDepth members of srtingBase
	{
		offset = (stringBase[idx].size() - subString.size()); //Calculate the length difference beteen the search string and the selected array string 

		if (offset == 0)
		{
			for (int idz = 0; idz < subString.size(); idz++) //Compair each char if the lengths are the same
			{
				if (subString[idz] == stringBase[idx][idz])
				{
					strCheck++;
				}
			}
			if (strCheck == subString.size()) //if the number of matched chars is the length of the search string, a match was found
			{
				return(idx);
			}
			else
			{
				strCheck = 0;
			}
		}
		else if (offset > 0) //If the lengths are different:
		{
			for (int idy = 0; idy <= offset; idy++) //Iterate through offset
			{
				for (int idz = 0; idz < subString.size(); idz++) //Compair each char, but offset the selected array string's starting point
				{
					if (subString[idz] == stringBase[idx][idz + idy])
					{
						strCheck++;
					}
				}
				if (strCheck == subString.size()) //if the number of matched chars is the length of the search string, a match was found
				{
					return(idx);
				}
				else
				{
					strCheck = 0;
				}
			}
		}
	}
	return(-1);
}

//Removes the string at a user-promted location from stringBase, returns the new length of stringBase
int removeString(int arrayDepth, string stringBase[MAX_STRINGS])
{
	int removeLoc = -1;
	bool valid_input = true;

	if (arrayDepth <= 0)
	{
		cout << "No strings to remove" << endl;

		return (arrayDepth);
	}

	cout << "Select a string to remove: ";
	valid_input = getInt(removeLoc);

	while ((removeLoc < 1) || (removeLoc > arrayDepth) || !valid_input) //Check if the entered index is within the array, otherwise, ask again
	{
		cout << "Invalid entry, enter again: ";
		valid_input = getInt(removeLoc);
	}

	if (removeLoc == arrayDepth) //Just return arrayDepth if user input is the last string
	{
		return (arrayDepth - 1);
	}

	for (int idx = --removeLoc; idx < arrayDepth; idx++)
	{
		stringBase[idx] = stringBase[idx + 1];
	}

	return (arrayDepth - 1);
}