I am getting errors when I'm trying the following:

instantiateVariable(string startingExpr, char var_, int val_)
{
    int sizeArray = startingExpr.length();

    //Convert the int into a char/string
    int number = val_;
    string newChar = "";
    ostringstream temp;
    temp << val_;
    newChar = temp.str();

    //Searching for the variable in the array
    for(int i = 0; i < sizeArray; i++)
    {
        //If the variable is in the string
        if(startingExpr[i] == var_)
        {
            //"Replace" the char with the converted int in the string
            startingExpr[i] = newChar;
        }
    }
}

The error says the following:

error: cannot convert 'std::string {aka std::basic_string<char>}' to 'char' in assignment

If anyone can tell me how to fix this I will REALLY appreciate it!

Thanks. :)

Dani AI

Generated

Short answer: the compile error comes from trying to put a std::string into a single char, and assigning an int to a char stores the numeric code (that's why you saw a weird symbol). As pointed out, convert the integer to a string before replacing. As and suggested, keep an immutable original expression and produce a modified copy so variables can be reassigned later.

Recommended pattern (keeps original, stores assignments, rebuilds the expression each time):

  • Keep originalExpr intact.
  • Store assignments in a map like std::unordered_map<char,std::string> vars_.
  • When a variable is set, update the map and regenerate modifiedExpr by replacing only full identifier tokens (not characters inside function names or numbers). That way repeated calls change values without destroying the original.

Example of a simple tokenization-based rebuild (novel approach, not the snippets already in the thread):

void Expression::setVar(char var, int val) {
    vars_[var] = std::to_string(val);        // C++11; use snprintf on older compilers
    modifiedExpr = applyVars(originalExpr);
}

std::string Expression::applyVars(const std::string& src) const {
    std::string out;
    size_t i = 0;
    while (i < src.size()) {
        if (std::isalpha(static_cast<unsigned char>(src[i]))) {
            size_t j = i;
            while (j < src.size() && std::isalnum(static_cast<unsigned char>(src[j])))
                ++j;
            std::string ident = src.substr(i, j - i);
            if (ident.size() == 1 && vars_.count(ident[0]))
                out += vars_.at(ident[0]);
            else
                out += ident;
            i = j;
        } else {
            out.push_back(src[i++]);
        }
    }
    return out;
}

Practical cautions: do not use zero-length arrays like char vars[0] (use std::vector or unordered_map), avoid assigning var_ = val_ when var_ is a char, and prefer std::to_string (or snprintf) to produce printable digits. If token rules are more complex, use std::regex with word boundaries or a proper lexer so function names and multi-char identifiers are not accidentally altered. Feed modifiedExpr to the shunting-yard/evaluator so it always uses the latest variable values.

Recommended Answers

All 17 Replies

startingExpr[i] is a char, and newChar is a string, so

startingExpr[i] = newChar;

makes no sense; you're trying to assign a string object to a char.

This being C++11, we have a to_string function now for converting an int to a string: http://en.cppreference.com/w/cpp/string/basic_string/to_string

I take you have something like "x + 5" and you want a function that searches the expression for the variable and replaces it with a number. To do that you can use this:

// make var_ a string to handle variables like "xx", "someval"
instantiateVariable(string startingExpr, string var_, int val_)
{
    size_t pos = 0;
    stringstream ss;
    // load int into string stream
    ss << val_
    // while we find the variable
    while ((pos = startingExpr.find(var_, pos)) != std::string::npos)
    {
        // at the spot of the variable replace the size of the variable
        // with the string contents of ss.
        startingExpr.replace(pos, var_.size(), ss.str());
        pos++;
    }
}

One question you need to ask is do you really need an int for this function or can you pass it a string that represents the value? If you pass it a string then the function becomes:

instantiateVariable(string startingExpr, string var_, string val_)
{
    size_t pos = 0;
    while ((pos = startingExpr.find(var_, pos)) != std::string::npos)
    {
        startingExpr.replace(pos, var_.size(), val_);
        pos++;
    }
}

I have not tested this but it should work.

Ok I am going to give you all my files so that you can see what I want to do.

in my ex.cpp I have this:

Expression::Expression(string expr)
{
    startingExpr = expr;
}

Expression::~Expression()
{
    cout << "Destructor" << endl;
}

void Expression::instantiateVariable(char var_, int val_)
{
    cout << startingExpr << endl;
    instantiateVariable(startingExpr,var_,val_);
}

void Expression::instantiateVariable(string startingExpr, char var_, int val_)
{

    stringstream nvs;
    string newVarString;
    char c = var_;
    nvs << c;
    nvs >> newVarString;

    size_t pos = 0;
    stringstream ss;
    ss << val_;

    while ((pos = startingExpr.find(newVarString, pos)) != std::string::npos)
    {
        startingExpr.replace(pos, newVarString.size(), ss.str());
        pos++;
    }
}

And in my main:

int main(int argc, char** argv)
{
    Expression expr("x + y + sqrt 25 - 3");

    expr.instantiateVariable('x',5);
    expr.instantiateVariable('y',3);
}

I just get this as the output:

x + y + sqrt 25 - 3
x + y + sqrt 25 - 3

While it must be:

5 + 3 + sqrt 25 - 3 (And only once)

If you can help me on this one I will REALLY REALLY appreciate it

void Expression::instantiateVariable(char var_, int val_)
{
    cout << startingExpr << endl;
    instantiateVariable(startingExpr,var_,val_);
}

Becomes

void Expression::instantiateVariable(char var_, int val_)
{
    instantiateVariable(startingExpr,var_,val_);
    cout << startingExpr << endl;
}

If you want to see what the expression look like after the replacement.

If you cant change the signature of

void Expression::instantiateVariable(string startingExpr, char var_, int val_)

Then you can use

instantiateVariable(string & startingExpr, char var_, int val_)
{
    size_t pos = 0;
    stringstream ss;
    ss << val_;

    while ((pos = startingExpr.find(var_, pos)) != std::string::npos)
    {
        // use one here since a char can only have 1 symbol.
        startingExpr.replace(pos, 1, ss.str());
        pos++;
    }
}

Notice I used a reference for startingExpr so that the function modifies the value. Otherwise you would need to return the string.

YOU ARE AWESOME!!!!!!!

It gives the following now:

5 + y + sqrt 25 - 3
5 + 3 + sqrt 25 - 3

So I assume when I want to pass this expession to a shuntingYard algorithm it will use the "latest/newest" one? In other words, the second output?

But thank you SO much! I really appreciate it! :)

the startingExpr member of your Expression class holds the final value which is 5 + 3 + sqrt 25 - 3

Member Avatar for Member #46692

One question you need to ask is do you really need an int for this function or can you pass it a string that represents the value?

^^This.

You're wasting your time converting it to an integer or double here.

Your method instantiateVariable is nothing more than string replace. Get this and you're 99% done, assuming your rpn stuff is working.

Member Avatar for Member #46692

Additionally, I might add for future reference please don't create new threads for your questions as it creates a disjointed effort by those contributing.

You other thread Click Here is very relevant to your question here. If others had known this they will have rightly pointed you to using string replace rather than what you're actually attempting to do.

There is no need to convert to an actual integer or double here as your shunting algo should be doing this.

Okay so bad news... It worked but its not working entirely as it should. Now I have the following:

void Expression::instantiateVariable(string startingExpr, char var_, int val_)
{
    for(int i = 0; i < startingExpr.length(); i++)
    {
        if(startingExpr[i] == var_)
        {
            var_ = val_;       //'Replace' x with 5  -  BUT HOW????
        }
    }
}

and then this:

instantiateVariable('x',5);

Because if I use strings, later on I won't be able to change the value of x if I use replace because then it will never pick up x again. It will only see the character I replaced x with.

How will I then go about this?

Because when I do this I get an output like the following:

♣ * (2 + 3) Instead of 5 * (2 + 3) 

Which is a total random char and not the one I tried to assign to x.

Member Avatar for Member #46692

Things to note.

-Just use string replace
-make sure the number you are replacing is a string to (this tends to confuse newbies, yes the number '5' can be represented as a string.

Therefore your function will pass in two parameters that are both strings (string a, string b).

If you need to reuse the original equation store that equation somewhere, that way you can always be sure you have access to the original equation with the letters as variables.

I understand perfectly. But how do I "store" the "original" string as you mentioned?

But how do I "store" the "original" string as you mentioned?

string stored_string = string_you_want_to_store;

I changed my code a bit and tried this:

void Expression::instantiateVariable(char var, int val)
{
    char vars[0];
    int vals[0];

    if(modifiedExpr == "")
    {
        modifiedExpr = originalExpr;
        vars[0] = var;
        vals[0] = val;
    }
    else
    {
        for(int i = 0; i < originalExpr.length(); i++)  //Searching for the var in the original expression
        {
            if(vars[i] == var)  //If the variable is found
            {
                modifiedExpr = originalExpr;    //Setting the expression to the original one so that x can be "replaced"
                vals[i] = val;  //Replace the variable with the value - Does not work :(((
                break;
            }
        }
    }

    //Testing the output if it works
    cout << modifiedExpr << endl;
}

It only gives me the original expression and not the modified "updated" expression. Can you please identify what I am doing wrong??

Member Avatar for Member #46692

Try changing your function to be both chars, (char val, char val2)

I'm not allowed to change that. :(

Member Avatar for Member #46692

I'm not allowed to change that. :(

Then I'm afraid you can't do it :D

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.