0

thanks for any help in advance and apologies if this is a double post, but I read through a few other questions and I didn't find the answer I was looking for.

I am working on a project where I have to input a string (String1) and then find a specific string (String2) within String1. Then I have to replace String2 with a new string (String3).

Hope that makes sense. Anyways, I am able to achieve the desired result, but it is situational. On to the code and I'll explain on the way.

int main() { string string1, from, to, newString; cout << "Enter string 1: "; getline(cin, string1); cout << "Enter string 2: "; cin >> from; cout << "Enter string 3: "; cin >> to; newString = replaceSubstring(string1, from, to); cout << "\n" << newString; } string replaceSubstring(string string1, string from, string to) { int index, n, x = 0; n = from.length(); while (x < string1.length() - 1) { index = string1.find(from, x); string1.replace(index, n, to); x = index + to.length() - 1; } return string1; } 

I am supposed to input the following: "He lived in this small town for a long time. He graduated in 1950."

And then I am supposed to replace all instances of "He" with "She".

When I attempt this I get the following error:

terminate called after throwing an instance of 'std::out_of_range'
what(): basic_string::replace
Abort (core dumped)

However, if I enter something like.

String1 = "He He"
String2 = "He"
String3 = "She"

It will output:

"She She"

4
  • 3
    Replacing "string1", "string2", and "string3" with meaningful variable names would make it easier to identify the behavior of your program. Commented Nov 17, 2014 at 18:56
  • I made a couple minor edits to change the variables. String2 = From and String3 = To. Since I'm changing From string2 To string3. Commented Nov 17, 2014 at 19:00
  • 1
    learn to use the debugger Commented Nov 17, 2014 at 19:15
  • In the current system I am using (UNIX) on campus there is no debugger. If I were at home I would do that. Unfortunately the only way of knowing if there are errors is compiling and then trying to work through them one at a time. Commented Nov 17, 2014 at 19:29

3 Answers 3

2

When your FIND call fails, you will have an incorrect index at this area:

 index = string1.find(string2, x); string1.replace(index, n, string3); 

Check the value of index before passing it into Replace

Sign up to request clarification or add additional context in comments.

3 Comments

@pm100 perhaps you can be more specific. A failed find returns -1, perhaps not a desirable value to use in the next Replace call
@grantly - I was commenting on mccdlibby saying that we was doing error checking. I upvoted yr answer as 100% correct
@pm100 Ah sorry my mistake, I misunderstood :)
1

First of all it would be better if the function would change the original string "in place". In this case it would look as a generic function replace similar to member function replace.

You shall check whether index after call

index = string1.find(string2, x); 

is equal to std::string::npos. Otherwise the function will throw an exception.

Also this statement

x = index + to.length() - 1; 

is wrong

It should look like

x = index + to.length(); 

For example assume that you have string with value "a" and want to substitute it for "ba". In this case if to use your statement x will be equal to 1 ( x = 0 + 2 - 1 ). and will point to "a" in "ba". And the function again will replace "a" to "ba" and you will get "bba" and so on. That is the loop will be infinite.

I would write the function the following way

#include <iostream> #include <string> void replace_all( std::string &s1, const std::string &s2, const std::string &s3 ) { for ( std::string::size_type pos = 0; ( pos = s1.find( s2, pos ) ) != std::string::npos; pos += s3.size() ) { s1.replace( pos, s2.size(), s3 ); } } int main() { std::string s1( "Hello world, world, world" ); std::string s2( "world" ); std::string s3( "mccdlibby" ); std::cout << s1 << std::endl; replace_all( s1, s2, s3 ); std::cout << s1 << std::endl; return 0; } 

The output is

Hello world, world, world Hello mccdlibby, mccdlibby, mccdlibby 

Comments

1

Find function returns the starting index of string x and index start from 0 to len-1 instead of 1 to len.

int idx = string1.find(string2, x); if(idx >= 0) string1.replace(index, n, string3); 

2 Comments

In general case it is a wrong code. For example if the original string is very long and std::string::size_type is equal to 8 bytes while int is equal to 4 bytes when you will get undefined behaviour.
if should be idx > std::string::npos

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.