How to retrieve multiple variables using a while loop

I have a challenge from a friend where I need to translate "pirate" phrases into english. For example,

arr = hello

I wrote down the list of the pirate words translated to normal english. However, it only takes one single word instead of all of them.
So if I put:

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
 #include <iostream>
#include <string>
using namespace std;

int main()
{

string str;

int i = 0;

int length = str.length();



cout << "Please enter a phrase (one or more words, all characters in lower case): ";
getline (cin, str);


 
if (str == "sir")
		cout << "matey." <<endl;
	
	if (str == "madam")
		cout << "proud beauty." << endl;
	
	if (str == "officer.")
		cout << "foul blaggart." << endl;




If I put in the phrase "sir" "madam" "officer" it doesn't recognize it. But it does recognize "sir" = "matey." So I'm basically asking on how to make the console recognize all of these in a sentence. combine these phrases using a while loop.
I think you want str.find() for each word in the line.

this approach is very challenging to work with for a large word list.
consider putting all the words and their translations into some sort of container so you can just swab one word for another easily using str.replace ??

closed account (E0p9LyTq)
You have the basics down, using std::getline to retrieve the entire line in a std::string.

To parse out the individual words create a std::stringstream from your input string and then loop reading the individual words in the stream as you would read from std::cin. Check to see if the failbit or eof isn't set and continue with another loop read.

https://en.cppreference.com/w/cpp/io/basic_stringstream
https://en.cppreference.com/w/cpp/io/basic_istream/operator_gtgt
Last edited on
With string streams you should note that you're losing white-spaces. So if there were 30 white-spaces, that wouldn't be observed in the output, only one white-space would (because we put one white-space between words).

Another thing to note is that string stream might fail if you have punctuation. So to counter this I have made it so that if there is only one successive character after the phrase then the program should still translate the phrase and preserve the character.

However that character need not be a punctuation, it could be any character. So those optimizations parts are up to you. You have to verify that it's actually a punctuation by adding another comparison.

Also note that the comparison will not consider cases. So if you write "Madam" then the program won't recognize it. If you want to recognize cases then you need to convert both the phrase and the comparison phrase to either uppercase or lowercase. You can use transform.

Anyways here's a demonstration.
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
#include <iostream>
#include <sstream>
#include <vector>
#include <string>

using namespace std;

struct pirate_words {
	string english_phrase;
	string pirate_phrase;
};

string translate_to_pirate(string phrase, vector<pirate_words> dictionary) {
	for (auto i : dictionary) {
		if (phrase.length()-1 == i.english_phrase.length()) {
			if (phrase.substr(0, phrase.length() - 1) == i.english_phrase)
				return i.pirate_phrase + phrase[phrase.length() - 1];
		}
		else if (phrase == i.english_phrase) {
			return i.pirate_phrase;
		}
	}
	return phrase;
}

int main()
{
	vector<pirate_words> dictionary = { {"sir", "matey" }, {"madam", "proud beauty"}, {"officer", "foul blaggart"} };
	string input;

	getline(cin, input);
	stringstream parse(input);

	string word;
	while (parse >> word)
		cout << translate_to_pirate(word, dictionary) << ' ';

	cin.get();
	return 0;
}

Hello madam, have you seen the officer?
Hello proud beauty, have you seen the foul blaggart?


Grime wrote:
With string streams you should note that you're losing white-spaces.

What do you mean by this? There's nothing special about string streams over other stream types with respect to whitespace.
Last edited on
Okie lemme rephrase.

If you are going to use the string stream approach that furry guy mentioned and for which I demonstrsted, note that because you are parsing word by word you won't be considering whitespaces and hence will lose all whitespaces from the original input.

Parsing word by word is the only reason you would be using string stream in this context. Otherwise you would just use strings.
Last edited on
I don't think the program is supposed to be that complex, and I'm only supposed to use <string>. I also don't recognize most of the functions/strings you used there.
Okay then you've got to use string::replace and string::find like Jonnin said.
http://www.cplusplus.com/reference/string/string/replace/
http://www.cplusplus.com/reference/string/string/replace/

If you cannot use a structure then just use two c-style arrays. And enclose the entire thing inside a for loop which iterates once per word in the array to find the word in the string.
Topic archived. No new replies allowed.