Originally Posted by
Daved
I would use string for both. It will be clearer and there really isn't much downside. You can make a string const as well if you wanted, although it's not necessary here.
If you're planning on using multiple parts of speech, you can also use an enum.
Code:
enum part_of_speech { noun, verb };
Then just use part_of_speech as your type instead of const char*. The only additional code you'd need is to convert the enum to a string. A simple function or array could do that if you went that route.
I'm experimenting with this to learn more about it. Say you've got a loop that reads words from files into each of the different parts of the map that these enum values refer to. That's what I could have in this program I'm making based around this stuff (it's intended to be part of a chat bot someday). Basically each file contains nouns, verbs, whatever, in the following format: "cat car dog door person wall" and so on. I've posted the relevant part of it up here to show what I mean.
Anyway in the program, I'm currently using this in the aforementioned loop, to transfer words from all the different files into the words map:
Code:
wordsmap.insert ( pair<string, const char*>(word1, wordtypes[filenum]) );
But say I change to using an enum. Can I still do something like this? I ask because I tried declaring an enum like this:
Code:
enum part_of_speech {adjective, adverb, noun, other, preposition, verb, newword};
And then using:
Code:
wordsmap.insert ( pair<string, part_of_speech>(word1, part_of_speech[filenum]) );
But it didn't work. So is there any way I can do that? As I mentioned I've posted up my code to show the context. Also if you see any other mistakes I've made I'd be glad to get some feedback about how I could improve it. Thanks.
Code:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#define NUM_OF_FILES 6
using namespace std;
const char* wordtypes[NUM_OF_FILES+1] = {"adjectives", "adverbs", "nouns", "other", "prepositions", "verbs", "new"};
vector<string> wordsdone;
multimap<string, const char*> wordsmap;
multimap<string, const char*>::iterator mmiter;
int main() {
char input_line[500];
string input_string, word1;
int stpos, endpos;
stpos = 0, endpos = -1;
int filenum = 0;
char filename[20];
char filenames[NUM_OF_FILES][20] = {"adjectives.txt", "adverbs.txt", "nouns.txt",
"other.txt", "prepositions.txt", "verbs.txt"};
strcpy_s(filename, filenames[filenum]);
ifstream file_in(filename);
cout << "Reading from file number " << filenum << ": ";
// Read different types of words from text files into appropriate vectors- nouns.txt into nouns vector etc.
// Also read words from chosen file into words vector.
while (filenum <= NUM_OF_FILES) {
// 1. Get a line of input and put it in input_string.
file_in.getline(input_line, 499);
input_string = input_line;
if (filenum == NUM_OF_FILES) // If it's from the text, make it all lower case.
for (stpos = 0; stpos < input_string.length(); stpos++)
if (input_string[stpos] >= 65 && input_string[stpos] <= 90) // capital letters
input_string[stpos] = tolower(input_string[stpos]);
// 2. Find individual words in input_string. 3. Add them to nouns/verbs/words depending on the file.
for (stpos = 0; stpos < input_string.length(); stpos++) {
// If a letter is found at the start of input_string, stop searching for a start position.
if (input_string[stpos] >= 97 && input_string[stpos] <= 122) {
for (endpos = stpos; endpos <= input_string.length(); endpos++) {
// If a non letter is found at the end of input_string, stop searching for an end position.
if (input_string[endpos] < 97 || input_string[endpos] > 122) {
word1.assign(input_string, stpos, endpos-stpos);
cout << word1 << ",";
if (filenum <= NUM_OF_FILES)
wordsmap.insert ( pair<string, const char*>(word1, wordtypes[filenum]) );
stpos = endpos; // check for a new word after this one, starting from endpos
// (endpos is currently at the first non-letter after the word.)
// Enter all the different words in worddone once- so the following classification bit
// doesn't ask for the type of the same word twice (although this doesn't really make sense
// because a word can have multiple types).
if (filenum < NUM_OF_FILES &&
find(wordsdone.begin(), wordsdone.end(), word1) == wordsdone.end())
wordsdone.push_back(word1);
break; // stop it going to the end of input_string in this for loop.
}
}
}
}
if (file_in.eof()) {
filenum++;
file_in.close();
file_in.clear();
if (filenum <= NUM_OF_FILES-1) {
strcpy_s(filename, filenames[filenum]);
file_in.open(filename);
}
else if (filenum == NUM_OF_FILES)
file_in.open("Readme.txt");
if (!file_in) {
ofstream file_out(filename);
cout << "(creating " << filename << ")";
file_out.close();
file_in.open(filename); // note this doesnt work yet. still dont know why.
}
if (filenum <= NUM_OF_FILES)
cout << endl << "Reading from file number " << filenum << ": ";
}
}
cout << endl << endl << "Finished reading from files." << endl << endl;
file_in.close();
return 0;
}