-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
339 lines (285 loc) · 10.7 KB
/
main.cpp
File metadata and controls
339 lines (285 loc) · 10.7 KB
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
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
/** Start by copying in your code from part IV.
* You need to finish part IV before starting
* part V.
*
*
**/
#include <iostream>
#include <fstream>
#include <cctype>
#define DEFAULT_DICT "dictionary1.txt"
#define DEFAULT_OUTPUT_FILE "dict-updated.txt"
#include "LinkedList.h"
#include "testll.h"
using namespace std;
enum Actions {QUIT, SHOW_WORD_COUNT, PRINT_TO_SCREEN, PRINT_TO_SCREEN_IN_REVERSE,
ADD_WORD, LINEAR_SEARCH, DELETE_WORD, INSERT_IN_ORDER, SWAP,
MERGE_DICTS, MERGE_SORT, LOAD_NEW_DICT, WRITE_DICT_TO_FILE, UNIT_TEST};
const int min_menu_option = 1; //not including Quit, which is zero
const int max_menu_option = UNIT_TEST;
const int min_dict_option = 1;
const int max_dict_option = 6;
int getMenuChoice();
void displayChoices();
void processInput(int userInt, LinkedList* currDict);
bool loadDict(LinkedList* currDict, string filename);
int getDictNum(const string& filename);
void loadDictPrompt(LinkedList* currdict);
string getDictName(int dictNum);
bool fileExists(const string& filename);
void writeToFile(LinkedList* currDict);
Node* findWord(LinkedList* currDict, string userWord);
void linearSearchPrompt(LinkedList* currDict);
void printSearchResult(Node* userNode, LinkedList* currDict);
void addWordPrompt(LinkedList* currDict);
string cleanInput(const string& userWord);
int main()
{
int userInt = -1; //random starter value out of range
LinkedList* currDict = new LinkedList;
loadDict(currDict, DEFAULT_DICT); //load default dictionary
while (userInt != QUIT) {
userInt = getMenuChoice();
processInput(userInt, currDict);
}
return 0;
}
string cleanInput(const string& userWord) {
string final = "";
for(unsigned int i = 0; i < userWord.length(); ++i) {
if(isalpha(userWord.at(i))) {
final.push_back(tolower(userWord.at(i)));
}
}
return final;
}
void addWordPrompt(LinkedList* currDict) {
string userWord;
string cleanedInput;
Node* userNode;
cout << "Enter a word to add to the end of the chosen Dictionary: ";
cin >> userWord;
cleanedInput = cleanInput(userWord);
cout << endl << "Your word was " << "'" << cleanedInput << "'." << endl;
userNode = findWord(currDict, cleanedInput);
if(userNode == nullptr) { //if not found
cout << " We did not find your word." << endl;
cout << " Adding word to dictionary...";
//addWord(currDict, userWord); adds word in the right spot
currDict->push_back(cleanedInput); //adds word to end
cout << " Added!";
//print result after adding word
printSearchResult(currDict->getLast(), currDict);
//extra details
cout << " There is no word after " << cleanedInput << ". It is the last word." << endl;
} else { //if word found
printSearchResult(userNode, currDict);
if (userNode->getNext() == nullptr) {
cout << " There is no word after " << cleanedInput << ". It is the last word." << endl;
}
}
}
void printSearchResult(Node* userNode, LinkedList* currDict) {
if(userNode == nullptr) { //if not found
cout << " We did not find your word." << endl;
} else if (userNode == currDict->getLast()){ //if first
cout << " The previous word would be '" << userNode->getPrev()->getData() << "'." << endl;
} else if (userNode == currDict->getFirst()) { //if last
cout << " The next word would be '" << userNode->getNext()->getData() << "'." << endl;
} else { //if found inbetween first and last
cout << " The previous word would be '" << userNode->getPrev()->getData() << "'." << endl;
cout << " The next word would be '" << userNode->getNext()->getData() << "'." << endl;
}
}
void linearSearchPrompt(LinkedList* currDict) {
string userWord;
Node* userNode = nullptr;
cout << "Enter a word to find: ";
cin >> userWord;
userWord = cleanInput(userWord);
cout << endl << "Your word was " << "'" << userWord << "'." << endl;
userNode = findWord(currDict, userWord);
printSearchResult(userNode, currDict);
}
Node * findWord (LinkedList * currDict, string userWord) {
Node* current = currDict->getFirst();
Node* location = nullptr;
if (current != nullptr) { //if list is not empty
do {
if (current->getData() == userWord) { //if match found
location = current; //store location
break; //exit loop
} else {
current = current->getNext(); //increment node
}
} while (current != nullptr);
}
return location;
}
bool fileExists(const string& filename) { //taken from vector dict
ifstream inFS;
inFS.open(filename); //try to read from file
bool exists = inFS.is_open(); //if successfully opened => file exists
inFS.close();
return exists;
}
void writeToFile(LinkedList* currDict) {
string userIn;
ofstream outFS;
Node* current = currDict->getFirst(); //take head of list
cout << "Enter name of file (.txt will be appended automatically), or enter 'd' to use default filename: ";
cin >> userIn;
cout << endl << endl; //for spacing
if (userIn == "d") {
userIn = DEFAULT_OUTPUT_FILE;
} else {
userIn = userIn + ".txt";
}
if (!fileExists(userIn)) {
cout << "Writing to file ...";
outFS.open(userIn);
if (!outFS.is_open()) {
cout << "error opening file to write";
return; //exit method
}
while (current != nullptr) {
outFS << current->getData() << endl;
current = current->getNext();
}
outFS.close();
cout << " ...Done!";
} else {
cout << "ERROR! The file " << userIn << " already exists. No data was written to file." << endl;
}
}
string getDictName(int dictNum) {
return "dictionary" + to_string(dictNum) + ".txt"; //return given int's filename;
}
void loadDictPrompt(LinkedList* currDict) {
int dictNum = getDictNum(currDict->getName()); //find current dictNum
int userNum;
bool leave = false;
bool openedDict;
while (!leave) {
//take user input
cout << "Which Dictionary should be opened? Enter a number from " << "\"" << min_dict_option << "\"" << " to " << "\"" << max_dict_option << "\"" << ": ";
cin >> userNum;
cout << endl; //for spacing
if (userNum == dictNum) {
cout << "That dictionary is already open! Pick another." << endl;
} else if (userNum < min_dict_option || userNum > max_dict_option) {
cout << "That number is not in the available range! Pick another." << endl;
} else {
openedDict = loadDict(currDict, getDictName(userNum)); //load appropriate dict
leave = true; //leave while
}
}
if (!openedDict) {
cout << "ERROR! Cannot read chosen dictionary " << getDictName(userNum) << ". Dictionary " << dictNum << " remains open." << endl;
} else {
cout << "Dictionary " << userNum << " is now open." << endl;
}
}
int getDictNum(const string& filename) { //get dictnum int from dict name
int dictNum = -1; // negative to indicate failure
string::const_iterator itr = filename.begin();
while (itr != filename.end()) { //iterate through string
if (isdigit((*itr))) {
dictNum = *itr - '0'; //initialize to first number encountered (finds int value by subtracting char values)
break; //exit loop
}
++itr;
}
return dictNum;
}
bool loadDict(LinkedList* currDict, string filename) {
string currWord;
ifstream inFS(filename);
if (!inFS.is_open()) {
return false;
}
currDict->clear(); //empty list
//fill list
while (!inFS.eof()) {
inFS >> currWord;
currDict->push_back(currWord);
}
inFS.close();
currDict->setName(filename); //update current dict name
return true;
}
void processInput(int userInt, LinkedList* currDict) {
switch(userInt) {
case QUIT:
cout << "Thank you! Bye!" << endl;
break;
case SHOW_WORD_COUNT:
cout << "There are " << currDict->size() << " words in dictionary #" << getDictNum(currDict->getName()) << ".";
break;
case PRINT_TO_SCREEN:
currDict->print();
break;
case PRINT_TO_SCREEN_IN_REVERSE:
currDict->print_reverse();
break;
case ADD_WORD:
addWordPrompt(currDict);
break;
case LINEAR_SEARCH:
linearSearchPrompt(currDict);
break;
case DELETE_WORD:
cout << " Coming soon!";
break;
case INSERT_IN_ORDER:
cout << " Coming soon!";
break;
case SWAP:
cout << " Coming soon!";
break;
case MERGE_DICTS:
cout << " Coming soon!";
break;
case MERGE_SORT:
cout << " Coming soon!";
break;
case LOAD_NEW_DICT:
loadDictPrompt(currDict);
break;
case WRITE_DICT_TO_FILE:
writeToFile(currDict);
break;
case UNIT_TEST:
promptUnitTest();
break;
}
}
int getMenuChoice() {
int userInt;
do {
displayChoices();
cin >> userInt;
if ((userInt < min_menu_option || userInt > max_menu_option) && userInt != 0) {
cout << " Error! Input must be a number between " << min_menu_option << " and " << max_menu_option << ", or 0 to exit.";
}
} while ((userInt < min_menu_option || userInt > max_menu_option) && userInt != 0);
return userInt;
}
void displayChoices() {
cout << "--------------------------------------------" << endl;
cout << "Options menu:" << endl;
cout << " (" << SHOW_WORD_COUNT << ") Count - get number of words in dictionary list\n";
cout << " (" << PRINT_TO_SCREEN << ") Print words to screen\n";
cout << " (" << PRINT_TO_SCREEN_IN_REVERSE << ") Print words to screen in reverse order\n";
cout << " (" << ADD_WORD << ") Add a word (to end of dictionary list)\n";
cout << " (" << LINEAR_SEARCH << ") Find a word (Linear Search)\n";
cout << " (" << DELETE_WORD << ") Find word, delete if found\n";
cout << " (" << INSERT_IN_ORDER << ") Find word, insert if not found (assumes words are sorted alphabetically)\n";
cout << " (" << SWAP << ") Swap two words\n";
cout << " (" << MERGE_DICTS << ") Merge two dictionaries (assumes words are sorted alphabetically)\n";
cout << " (" << MERGE_SORT << ") Sort words (Merge Sort)\n";
cout << " (" << LOAD_NEW_DICT << ") Load a dictionary (closes current dictionary)\n";
cout << " (" << WRITE_DICT_TO_FILE << ") Write current dictionary to file\n";
cout << " (" << UNIT_TEST << ") Unit test of data structure\n";
cout << "Enter a number from " << SHOW_WORD_COUNT << " to " << UNIT_TEST << ", or " << QUIT << " to exit: ";
}