Joe_B
Joe_B

Reputation: 219

Replacing a specific char in a string with a value

I want to replace a specific char in a string and I have the following code to try this, but it does not work as I have hoped. It just outputs the original string.

What am I doing wrong?

#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

void instantiateVariable(string expr, char var_, int val_){
    replace(expr.begin(), expr.end(), 'var_', 'val_');
    cout << expr;
}

int main()
{
    string expr_ =  "x + (3 + 4)";
    instantiateVariable(expr_, 'x', 3);
}

Upvotes: 0

Views: 201

Answers (3)

bikeshedder
bikeshedder

Reputation: 7487

replace works on elements and not substrings. Therefore you can only use it to replace a single characters by one other character. You can use the find algorithm however and use the returned iterator as input for the string:replace method. As var_ is an integer and not a string it also needs to be converted first. I prepared a small example code for you which shows how you could use find, string::replace and ostringstream which does exacly that:

#include <iostream>
#include <string>
#include <algorithm>
#include <sstream>

using namespace std;

template<typename T>
string makestr(const T& val_)
{
    std::ostringstream buf;
    buf << val_;
    return buf.str();
}

void instantiateVariable(string expr, char var_, int val_)
{
    string::iterator it = find(expr.begin(), expr.end(), var_);
    if (it != expr.end())
    {
        expr.replace(it, it+1, makestr(val_));
    }
    cout << expr;
}

int main()
{
    string expr_ =  "x + (3 + 4)";
    instantiateVariable(expr_, 'x', 22);
}

Edit: Now that I think about it, I would rather use string::find in favor of the find algorithm as it requires less code and looks a lot more intuitive:

void instantiateVariable(string expr, char var_, int val_)
{
    size_t i = expr.find(var_);
    if (i != string::npos)
    {
        expr.replace(i, 1, makestr(val_));
    }
    cout << expr;
}

Hint: If you are using C++ 11 you can use std::to_string instead of the makestr function.

Upvotes: 3

usta
usta

Reputation: 6869

Remove the single quotes around var_ and val_:

replace(expr.begin(), expr.end(), var_, val_);

Then, change the call to:

instantiateVariable(expr_, 'x', '3');

Finally, instantiateVariable modifies a local copy of the string argument, rather than the argument itself. If you want to modify the actual argument, take expr by reference:

void instantiateVariable(string &expr, char var_, int val_)

Edit: The above is still wrong because var_ is char and val_ is int, and you need the types to match to call std::replace(). The deep problem here is that std::replace() is not the proper algorithm if I understand your needs correctly. E.g. if you decide to replace 'x' with the value 15, then you can't do that with std::replace(). I would use boost::algorithm::replace_all() combined with boost::lexical_cast if I were to implement such a thing.

Upvotes: 3

Logicrat
Logicrat

Reputation: 4468

Two things: One is, you are sending replace() the names of your variables instead of their values, that just won't work at all. Second is, for your second parameter your should use a character value, e.g., '3', instead of an integer value.

Upvotes: 1

Related Questions