Problem with Strings

I am trying to write a program that takes sms phrases like brb or lol and replaces them with the proper terms like be right back or laugh out loud.

I am having trouble with trying to setup a proper loop that won't behave improperly by only altering one section of the string.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
string eng(string str)
{
	size_t found;

	for (int i = 0; i < str.length(); ++i){ //replaces all the upper case text user inputted with lower case.
		str[i]=tolower(str[i]);
	}
	
	found = str.find("btw"); //searches the string for btw.

	if (found != string::npos){ //replaces that position of btw with by the way.
	        str.replace(str.find("btw"),str.length(),"by the way");
	}

	cout << str << endl; //outputs the string after editing.
	return (str);
}



This is what I am using now just trying to get it to find one of the phrases btw and replace it at the moment. It has some unforeseen problems like removing what the user places after btw. I have not been able to get this to work with a while loop so it can replace each btw if the user enters it 2 or more times.

The main function just asks the user to enter in the sms phrase that he wants translated before this basically.
Last edited on
IIRC, the second parameter of replace() should be the length of the string to replace. In this case, it's 3 (the length of "btw").
Yeah thanks I am still wondering why I can't make this into a while loop though. It works fine with this for the one instance of the term but if the message the user inputs is:

hey btw btw

It comes back..

hey by the way btw
Last edited on
Uh, can you show us what exactly you are doing there?
Yeah I put in some comments. I hope that explains better.
/* Have you considered using a map to perform the conversion?
* below is a short example. Change it to suit your purposes.
* Cheers mikeofthenight
*/

#include <iostream>
#include <map>
#include <string>
using namespace std;

int main()
{


map <string,string> abbrev; // create and fill a map
abbrev["btw"] = "By the way";
abbrev["lol"] = "Laugh out loud";
abbrev["stl"] = "Standard Template Library";
abbrev["cpp"] = "C PLUS PLUS";
// and so on

string name; // Now perform a lookup of the abbreviation
cout << "tEnter your abbreviation or 'quit' to quit: ";

while (cin >> name && name != "quit")
if (abbrev.find(name) != abbrev.end())
cout << "The conversion for " << name
<< " is " << abbrev[name] << "n";
else
cout << "Sorry, no listing for " << name << "n";

return 0;
}
Well that would be fine but its supposed to like I said take a full message in and then convert it.

Like user inputs:

Hey I will brb lol

converts to..

hey i will be right back laugh out loud

or if the user enters:

l8r bro I will brb

converts to..

later bro i will be right back
Last edited on
Uh, here. I made a full program out of what you want to do. I'll post it here for the lulz while I am still waiting for you to post your full code so we can see what's wrong with it.
(PS: the code won't compile like that. Not my fault, posting here eats my escape characters)
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
#include <iostream>
#include <string>
#include <map>
#include <locale>
using namespace std;

string& replace(string&, const map<string,string>&);

int main(int argc, char** argv)
{
	cout<<"Hello! This program will replace parts of a string based on user input"<<endl;
	cout<<"Attention: Recursive replacements are not possible, e.g. in the replacement of"<<endl<<
	""lol" into "lol: laughing out loud" the new "lol" will be ignored"<<endl;
	map<string,string> wordMap;
	string wordInput, replaceInput, commandInput;
	pair<map<string,string>::iterator, bool> mapCheckPair;
	while(commandInput.compare("no"))
	{
		commandInput = "";
		cout<<"Enter the word or word sequence to be replaced: ";
		getline(cin, wordInput);
		cout<<"Enter the word or word sequence it should be replaced by: ";
		getline(cin, replaceInput);
		mapCheckPair = wordMap.insert(pair<string,string>(wordInput, replaceInput));
		if(!mapCheckPair.second)
		{
			while(commandInput.compare("yes") && commandInput.compare("no"))
			{
				cout<<"The word"<<(*(mapCheckPair.first)).first<<"is already being replaced by"<<
					(*(mapCheckPair.first)).second<<endl<<
					"Change this replacement?[yes/no]: ";
				getline(cin,commandInput);
				locale loc;
				for(int i=0; i<commandInput.length(); ++i)
				{
					commandInput[i] = tolower(commandInput[i], loc);
				}
				if(!commandInput.compare("yes"))
				{
					wordMap.erase(mapCheckPair.first);
					wordMap.insert(pair<string,string>(wordInput, replaceInput));
				} else if(commandInput.compare("no"))
				{
					cout<<"Error, invalid input."<<endl;
				}
			}
			commandInput = "";
		}
		while(commandInput.compare("yes") && commandInput.compare("no"))
		{
			cout<<"Enter another word replacement? [yes/no]: ";
			getline(cin, commandInput);
			locale loc;
			for(int i=0; i<commandInput.length(); ++i)
			{
				commandInput[i] = tolower(commandInput[i], loc);
			}
			if(commandInput.compare("yes") && commandInput.compare("no"))
			{
				cout<<"Error, invalid input."<<endl;
			}
		}
	}
	cout<<"Now, please enter the string the changes should be applied to: ";
	getline(cin, wordInput);
	cout<<"The resulting string is: "<<endl;
	cout << replace(wordInput, wordMap);
	return 0;
}

string& replace(string& str, const map<string,string>& wordMap)
{
	int pos;
	int lastpos;
	for(map<string,string>::const_iterator it = wordMap.begin(); it!= wordMap.end(); it++)
	{
		lastpos = 0;
		do
		{
			pos = str.find((*it).first, lastpos);
			if(pos!=string::npos)
			{
				str.replace(pos,(*it).first.length(),(*it).second);
			}
			lastpos = pos;
		} while(pos!=string::npos);
	}
	return str;
}
Last edited on
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
#include <iostream>
#include <string>
#include <cctype>
using namespace std;

string sms();
string eng();

string eng(string str)
{
	size_t found;

	for (int i = 0; i < str.length(); ++i){
		str[i]=tolower(str[i]);
	}

	found = str.find("brb");

	if (found != string::npos){
		str.replace(str.find("brb"),3,"be right back");
	}

	found = str.find("btw");

	if (found != string::npos){
		str.replace(str.find("btw"),3,"by the way");
	}

	found = str.find("fwiw");

	if (found != string::npos){
		str.replace(str.find("fwif"),4,"for what it's worth");
	}

	found = str.find("gr8");

	if (found != string::npos){
		str.replace(str.find("gr8"),3,"great");
	}

	found = str.find("imho");

	if (found != string::npos){
		str.replace(str.find("imho"),4,"in my humble opinion");
	}

	found = str.find("l8r");

	if (found != string::npos){
		str.replace(str.find("l8r"),3,"later");
	}
	
	found = str.find("omw");

	if (found != string::npos){
		str.replace(str.find("omw"),3,"on my way");
	}

	found = str.find("np");

	if (found != string::npos){
		str.replace(str.find("np"),2,"no problem");
	}

	found = str.find("tmi");

	if (found != string::npos){
		str.replace(str.find("tmi"),3,"too much information");
	}

	found = str.find("ttyl");

	if (found != string::npos){
		str.replace(str.find("ttyl"),4,"talk to you later");
	}

	found = str.find("wywh");

	if (found != string::npos){
		str.replace(str.find("wywh"),4,"wish you were here");
	}

	cout << str << endl;
	return (str);
}

string sms(string str)
{
	size_t found;

	for (int i = 0; i < str.length(); ++i){
		str[i]=tolower(str[i]);
	}

	found = str.find("be right back");

	if (found != string::npos){
		str.replace(str.find("be right back"),13,"brb");
	}

	found = str.find("by the way");

	if (found != string::npos){
		str.replace(str.find("by the way"),10,"btw");
	}

	found = str.find("for what it's worth");

	if (found != string::npos){
		str.replace(str.find("for what it's worth"),19,"fwiw");
	}

	found = str.find("great");

	if (found != string::npos){
		str.replace(str.find("great"),5,"gr8");
	}

	found = str.find("in my humble opinion");

	if (found != string::npos){
		str.replace(str.find("in my humble opinion"),20,"imho");
	}

	found = str.find("later");

	if (found != string::npos){
		str.replace(str.find("later"),5,"l8r");
	}
	
	found = str.find("on my way");

	if (found != string::npos){
		str.replace(str.find("on my way"),9,"omw");
	}

	found = str.find("no problem");

	if (found != string::npos){
		str.replace(str.find("no problem"),10,"np");
	}

	found = str.find("too much information");

	if (found != string::npos){
		str.replace(str.find("too much information"),20,"tmi");
	}

	found = str.find("talk to you later");

	if (found != string::npos){
		str.replace(str.find("talk to you later"),17,"ttyl");
	}

	found = str.find("wish you were here");

	if (found != string::npos){
		str.replace(str.find("wish you were here"),18,"wywh");
	}

	cout << str << endl;
	return(str);
}

void main()
{
	string str, junk;
	
	int number = 1;

	while (number != 3){

		cout << "Welcome to the english/sms translator service" << endl;
		cout << "1) translate english to sms" << endl;
		cout << "2) translate sms to english" << endl;
		cout << "3) quit" << endl;
		cout << "Enter choice: ";
		cin >> number;
		getline(cin, junk);

		if (number == 1){
			cout << "Enter an english sentence or phrase: ";
			getline(cin, str);
			sms(str);
		}
		if (number == 2){
			cout << "Enter a sms sentence or phrase: ";
			getline(cin, str);
			eng(str);
		}
	}

}


There ya go the entire thing I have so far!
Last edited on
Uh, it does work. But for every single word you need to loop until all words are replaced, like this:

1
2
3
4
5
6
7
8
while(found!=string::npos)
{
found = str.find("brb");

	if (found != string::npos){
		str.replace(str.find("brb"),3,"be right back");
	}
}


Do that for all words and it should work- in theory anyways. I didn't check for other errors you might have made.

PS: Mine is more beautiful, though I better won't say this aloud, it will only attract people that give me a long list of what I have done wrong with it :O
EDIT: See, I already found the first error in my prog. My prevention of recursive replacement doesn't work (line 85 should be lastpos = pos + (*it).second.length();)
Last edited on
Yeah when I put in that exact snippet of code and then try to run it it gives me an error once I try to input a line of text after I pick option 2.

run-time check failure #3 - The variable 'found' is being used without being initialized.

All I did was take my code then add that before each found and if statement just like you have it.
Last edited on
You need to set found to 0 (or any other value except for string::npos) before entering any of these loops, look closely at the code and you'll understand why.
Okay thanks once I set up multiple variables for found that worked!
You don't need to do that... just set found to 0 before every loop
/* Have you tried using a map to perform the conversion?
* below is a short example. Change it to suit your purposes.
* Cheers mikeofthenight
*
* Well that would be fine but its supposed to like I said take a full message in and then convert it.
* Like user inputs: Hey I will brb lol
* converts to..
* hey i will be right back laugh out loud
* or if the user enters: l8r bro I will brb
* converts to.. later bro i will be right back
*
* Well a map can do that quite easily
* along with a small replace function.
* Cheers mikeofthenight
*/

#include <iostream>
#include <sstream>
#include <map>
#include <string>

using namespace std;

// Sreplace(OutputString,abbreviation,full sentence)
bool Sreplace(string &str,const string &orig,const string &newstr);



int main()
{


map <string,string> abbrev; // create and fill a map
abbrev["btw"] = "by the way";
abbrev["lol"] = "laugh out loud";
abbrev["l8r"] = "later";
abbrev["stl"] = "Standard Template Library";
abbrev["cpp"] = "C PLUS PLUS";
abbrev["brb"] = "be right back";
// and so on

cout << "Enter a sentence containing abbreviations: ";
string line,name; // create two strings
getline(cin,line); // get the sentence
name=line; // copy sentence to name string
istringstream istr(line); // create a input stream using line string

while (istr >> line) { // for each word in the string
if (abbrev.find(line) != abbrev.end()) // if it matches in the map
while (Sreplace(name,line,abbrev[line])); // then replace the abberviation with the full sentence.
}

cout << "Result:nt" << name << endl; //

return 0;

}


bool Sreplace(string &str,const string &orig,const string &newstr){
string::size_type idx = str.find(orig); // find abbreviation
if (idx != string::npos){ // if we find it then
str.replace(idx,orig.size(),newstr); // replace abbrev with new string
return true; // and return true
}
return false; // if not found return false
}
Mike, have you seen my code? It does just that, just that the function takes a dictionary right away :O
Re your code: I must have missed that when I looked through
all the masses of code that this question posed.
Regards mikeofthenight
Topic archived. No new replies allowed.