Parsing Matching Multiple Possible Strings in a Text Adventure. - c++

I'm in my first semester of university and I have to make a text adventure game in c++.
So far we've done arrays, structs, and pointers. I've tried to google my problem, however most other users use classes which we have not yet done.
The professor would like us to use commands like Go North, open door with key etc.
I've managed to make it work by using hotkeys like n to go north, but obviously I would like to do it like he wants us to.
So my question is; how can I make a command consisting of several strings?
The problem is that we need to create libraries for the command, the object and (if there is the possibility in this room to combine two things) the preposition with another object. In each library there should be the words to use, for example: Commands are: Use, go, talk, read, etc...

Taken from http://www.cplusplus.com/reference/iostream/istream/getline/
#include <iostream>
using namespace std;
int main () {
char name[256], title[256];
cout << "Enter your name: ";
cin.getline (name,256);
cout << "Enter your favourite movie: ";
cin.getline (title,256);
cout << name << "'s favourite movie is " << title;
return 0;
}

Try search for the getline or scanf function. Both reads a formatted string from the stdin(in your case the prompt command). You could use cin directly too, the problem is that cin return a string composed of the characters until the first whitespace.

If you're asking how to read the multi-word commands, then you can use getline() to read a line of input as a string, and then a stringstream to read each word from that line, something like this:
std::string line;
while (std::getline(std::cin, line)) {
std::istringstream stream(line);
std::string word;
while (stream >> word) {
// do something with this word
}
}

Use something like std::string input << std::cin; to input a line of text.
Split your string by whitespace/the space character.
Next steps:
Do command tokenization into verb/noun pairs, like Open/Door and Go/North
Make classes that represent your verbs, and design them to operate on objects or specific nouns
Some subjects to look up:
Text adventure command parsing on google
Interactive fiction on wikpedia

I guess you are using cin to read the commands? In that case get input into a string, use find to find the spaces in it, and substr to extract the command and its arguments. Try to convert all substrings to either lower- or upper-case, as it will be easier to compare them later.
Now take the command substring and compare it to all commands you have. When you find a match, call a special function that executes the command, passing the arguments to the function. E.g., for the "go" command you could have a go function, which takes the direction as argument.

Related

C++ Beginner: std::cin to std::string

Just started learning C++ and encountered an issue with strings while doing an exercise.
So I initialized std::string phrase; while allowing the user to input and save the phrase to the string with std::cin >> phrase;. Now my issue comes when the inputed phrase has spaces, I noticed that the computer will only save the characters up till the first word only.
With the phrase "sunsets are great", the phrase.size() only came out to 7, so the following words after the first space were not saved.
The entire exercise is supposed to compare all of the letters in the whole inputted string with another set of values. Should I be using a different function for this?
Any help would be appreciated! :)
I have also had this problem when i was first starting out.
whenever you want to read a string i would use the getline.
ie
string phase
cout << "enter phase" <<endl;
getline(cin,phase);
If you want to take an entire line including space(s), you may use the following code:
string str; // declaration
getline(cin, str);
Remember: cin.get and cin will trim all the inputted characters just after first space.
Enjoy.

Is it possible to skip a line in a data file?

I have a data file that I am trying to input and the data is split into sections via a blank line. The data will be read in from a text file.
How do I make my code skip a blank line to read in the next piece of data? I am currently just in the planning stages of my application.
I'm a beginner so I'm not really sure how to go about this.
Can anyone advise a method on how to approach this?
I have just written it out and my code looks like this:
string ship2_id;
char ship2_journey_id[20];
float ship2_l;
int ship2_s;
getline(itinerary_file, ship2_id);
if (ship2_id = ' ')
{
itinerary_file.ignore(numeric_limits<streamsize>::max(), '\n');
}
else
getline(itinerary_file, ship2_id);
cout << ship2_id << endl;
Yes,
stream.ignore(max_number_of_chars_to_be_skipped, '\n');
I usually just use 1ul<<30 or similar for the first parameter, but
this could be a DoS vector if the input is untrusted and slow to skip those chars
the "pedant" value would read std::numeric_limits<std::stream_pos>::max() or similar
I don't what are you using to read the file, but, to search for a blank line, look for two "line breaks" together. Take in account that the "line breaker" character is different for some OS. In Windows, by default, there are two characters that are used together for a line break.

Splitting user input by one space for the first two words, then storing the remaining phrase (C++)

Right now I'm trying to, and as the title says, find a way to split a string in a weird way.
Lets say the input looks like:
1234.5/N 1222.2/W Taco Tuesday
And the input given for the first two words separated by spaces will always be in the format #.#/(N/S/W/E)
The problem I'm having is with the last word. This word can be as many spaces as it wants to be and is only "terminated" by a newline.
My first try was doing:
std::string input1; // number/Letter
std::string input2; // number/Letter
std::string input3; // word
std::cin >> input1 >> input2 >> input3;
The problem is, obviously is that if input 3 has a space in it, cin won't capture anything past that last space.
I thought about using getline(cin, input), but I realized I would get a single string with everything in it, instead of 3 separate strings. I believe this would be more challenging to extract the numbers out of the first two (probably by using find(/)), somehow keeping the letter after the slash, then moving to the next number, extracting that, keeping the letter after, and finally getting the rest of the phrase, minus the letter after the slash.
Also I would have to store the numbers in separate variable for calculations, take note of the letter used, and keep the last phrase.
Is there any reasonably elegant way to do this using std::string or at the very least is there just some way to at least extract the first two words and then store the remaining phrase into a string?
You can try to read first two words with cin and then use getline:
cin >> input1 >> input2;
getline(cin, input3);

Good way to tokenize a string to store values? Or alternative for user input

Hello again Stackoverflow, I'm here again asking a question for my C++ programming class. The problem I am facing is mostly to due with user input from the keyboard. I need to be able to take the user input to decide what function to call and what arguments to give the function. For example something like add 5 would call the add function with the argument 5. At first I tried overloading the >> operator to take both a string and an int but the problem I ran into was the program was unable to take input without the int such as deletemax so I had to throw that idea out. So now I am back to tokenizing the input but we are not allowed to use Boost for this program so I came up with something like this using sstream
bool out = false;
string token;
string In;
int num;
do
{
cout << "heap> ";
cin >> In;
istringstream iss(In);
while(getline(iss, token, ' '))
{
cout << token << endl; //I know this is incorrect but just not what to replace it with
}
out = ProcessCommand (token, num); //Takes string and int to call correct functions
} while (out != true);
The problem lies in that I'm not quite sure how to correctly tokenize the string so I can get 2 string and convert the second string to an int. Can anyone offer me some assistance? I would greatly appreciate it. Also if there is a better way to go about this than I am trying I would also like to hear it.
Thanks for any help you can give me.
Googling "C++ string tokenize" will get you plenty of hits, with the first hit being on Stackoverflow. But you should take a stab at it. I'm guessing it's the point of the exercise.
You said "argumentS", which suggests that commands you support take varying numbers of arguments. I'd break it down like this:
read a line from the user
split line into 'tokens' on space boundaries, store tokens in a list
based on the first token in the list, choose a command to execute
pass the list of tokens to the command, so it can validate/interpret them as arguments
The tricky part is #2. Do you know about container classes yet? You can use vector<string> to store the chunks you parse. To do the actual parsing, you iterate through the characters of the string. Skip whitespace until you find a non-whitespace character (or run out of characters). Save this position: start. Then skip non-whitespace until you find whitespace (or run out of characters). Save this position: end. Copy the substring represented between from start to end and copy that to your token list.
Working out the actual details of this, making sure you don't have off-by-on-errors, etc. is going to be challenging if you've never done it before, which I'm guessing is the point.
You don't need to read in the whole of user input all at once.
For example you could read in the first bit of user input (the operation, add or deletemax, etc). From there depending on the operation you could continue to read arguments from input (in the case of add) or begin performing the operation immediately (in the case of deletemax).
One way would be to have a std::map of function names as keys and required number of arguments as values. You'd read a line of input, get the function name and then decide whether you need aditional arguments. I'd write a function that'd return a vector of arguments extracted from a string stream or an empty vector in case the input was invalid.

Working with strings in C++

I'm working with strings in C++. I recently came across a problem when entering strings. I'm using cin >> string; to get my string as user input. When the user enters a space into the string, the next input is automatically filled out with the remaining letters, or sometimes left blank. As the next input string is often an integer, this will result in an unpleasant bug. What's a good fix for this?
EDIT: Here's the current code:
cout << "Please print the enemy's name: ";
getline(cin, enemyName);
You probably want to get all input into the string up until the user presses enter. In that case, it can be said that what you really want is to read a "line" of text. To do that, you'd use std::getline, like so:
std::getline(cin, enemyName);
That is assuming enemyName is defined as an std::string. If enemy name is a c-style charater array, you'd want to use cin.getline, like this:
cin.getline(enemyName, sizeof(enemyName));
But, try to avoid using C-style character arrays at all in C++.
The behavior of >> with strings is intentional; it interprets whitespace characters as delimiters to stop at, so it's really best at chomping words. std::getline() (#include <string>) uses '\n' as the delimiter by default, but there's also a version of std::getline() that takes a custom delimiter character if you need it.
Use getline(cin, string); instead.
Use getline() to read in an entire line at a time.
getline (cin, string);