在不指定特定元素的情况下覆盖向量中的元素

Overwrite the elements in a vector without specifying specific elements

我正在制作一个可以同时接受多个运算符的计算器。我有一个向量对,用于存储运算符的位置和运算符的类型。向量必须在每次循环后更新,因为先前的位置由于结果替换了输入字符串的一部分而不再有效。

我尝试使用 clear() 以便它再次从头开始,但结果是 Expression: vector iterators incompatible。我不认为我可以使用 std::replace 因为字符串中的运算符数量在每次循环后都会发生变化。有没有办法让它从头开始并覆盖任何现有元素?

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

int main()
{
    std::cout << "C++ Calculator" << std::endl;

    while (true) //runs forever with loop
    {
        std::string input;
        std::getline(std::cin, input);

        //erases whitespace
        int inp_length = input.length();
        for (int i = inp_length - 1; i >= 0; --i)
        {
            if (input[i] == ' ')
                input.erase(i, 1);
        }
        
        std::vector<std::pair<int, char>> oper_pvec;
        int vec_pos = 0;

        //finds the position of operators and type
        for (std::string::iterator i = input.begin(); i != input.end(); ++vec_pos, ++i)
        {
            switch (*i)
            {
                case 'x':
                {
                    oper_pvec.push_back(std::pair<int, char>(vec_pos, 'x'));
                    break;
                }
                case '/':
                {
                    oper_pvec.push_back(std::pair<int, char>(vec_pos, '/'));
                    break;
                }
                case '+':
                {
                    oper_pvec.push_back(std::pair<int, char>(vec_pos, '+'));
                    break;
                }
                case '-':
                {
                    oper_pvec.push_back(std::pair<int, char>(vec_pos, '-'));
                    break;
                }
            }
        }

        //declarations before loop to make sure they're all able to be accessed, will probably change later
        int loper_pos = 0; //must be set 0 since there's no left operator at first
        int roper_pos;
        double lnum; //left number
        double rnum; //right number
        char loper; //left operator
        char roper; //right operator
        int pos = -1; //position of loop, needs to be -1 since it increments it each time
        std::string holder = input; //copy of input

        auto op = oper_pvec.begin();
        while (op != oper_pvec.end())
        {
            op = oper_pvec.begin();
            ++pos; //position of loop
            int key = std::get<0>(*op); //gets first value from vector pair
            char val = std::get<1>(*op); //gets second value from vector pair


            //gets previous/next vector pairs
            std::vector<std::pair<int, char>>::iterator prev_op = oper_pvec.begin();
            std::vector<std::pair<int, char>>::iterator next_op = oper_pvec.end();

            if (op != oper_pvec.begin()) prev_op = std::prev(op);
            if (op != oper_pvec.end()) next_op = std::next(op);


            //extracts the value of pairs
            if (pos > 0)
            {
                loper_pos = std::get<0>(*prev_op);
                loper = std::get<1>(*prev_op);
            }
            if (pos == oper_pvec.size() - 1) roper_pos = oper_pvec.size();
            else
            {
                roper_pos = std::get<0>(*next_op);
                roper = std::get<1>(*next_op);
            }


            //replaces numbers and etc with product, only multiplication for now
            switch (val)
            {
                case 'x':
                {
                    int lnum_start = loper_pos + 1;
                    if (loper_pos == 0) lnum_start = 0;

                    int lnum_len = key - (loper_pos + 1);
                    if (loper_pos == 0) lnum_len = key;

                    lnum = std::stod(input.substr(lnum_start, lnum_len));

                    int rnum_start = key + 1;
                    int rnum_len = (roper_pos - 1) - key;
                    rnum = std::stod(input.substr(rnum_start, rnum_len));

                    double prod = lnum * rnum;
                    std::string to_string = std::to_string(prod);
                    input.replace(loper_pos, roper_pos, to_string);
                    break;
                }
            }

            /////////////////////////////////problem area////////////////////////////////////////

            //clears the vector and then finds the operators again
            oper_pvec.clear();
            int vpos = 0;
            for (std::string::iterator it = input.begin(); it != input.end(); ++vpos, ++it)
            {
                if (vpos == input.length())
                {
                    vpos = 0;
                    break;
                }
                switch (*it)
                {
                    case 'x':
                    {
                        oper_pvec.push_back(std::pair<int, char>(vpos, 'x'));
                        break;
                    }
                    case '/':
                    {
                        oper_pvec.push_back(std::pair<int, char>(vpos, '/'));
                        break;
                    }
                    case '+':
                    {
                        oper_pvec.push_back(std::pair<int, char>(vpos, '+'));
                        break;
                    }
                    case '-':
                    {
                        oper_pvec.push_back(std::pair<int, char>(vpos, '-'));
                        break;
                    }
                }
            }
            /////////////////////////////////////////////////////////////////////////////////////
        }
        //converts to double then prints on screen
        double out = std::stod(input);
        std::cout << out << std::endl;
    }
}

不是标题的真正答案,而是我没有尝试覆盖向量,而是继续使用 clear() 并将 while 循环更改为 oper_pvec.size() != 0

(完整代码,因为我必须更改很多东西才能使其正常工作)

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

int main()
{
    std::cout << "C++ Calculator" << std::endl;

    while (true) //runs forever with loop
    {
        std::string input;
        std::getline(std::cin, input);

        //erases whitespace
        int inp_length = input.length();
        for (int i = inp_length - 1; i >= 0; --i)
        {
            if (input[i] == ' ')
                input.erase(i, 1);
        }
        
        std::vector<std::pair<int, char>> oper_pvec;
        int vec_pos = 0;

        //finds the position of operators and type
        for (std::string::iterator i = input.begin(); i != input.end(); ++vec_pos, ++i)
        {
            switch (*i)
            {
                case 'x':
                {
                    oper_pvec.push_back(std::pair<int, char>(vec_pos, 'x'));
                    break;
                }
                case '/':
                {
                    oper_pvec.push_back(std::pair<int, char>(vec_pos, '/'));
                    break;
                }
                case '+':
                {
                    oper_pvec.push_back(std::pair<int, char>(vec_pos, '+'));
                    break;
                }
                case '-':
                {
                    oper_pvec.push_back(std::pair<int, char>(vec_pos, '-'));
                    break;
                }
            }
        }

        //declarations before loop to make sure they're all able to be accessed, will probably change later
        int loper_pos = 0; //must be set 0 since there's no left operator at first
        int roper_pos;
        double lnum; //left number
        double rnum; //right number
        char loper; //left operator
        char roper; //right operator
        int pos = -1; //position of loop, needs to be -1 since it increments it each time
        std::string holder = input; //copy of input

        std::vector<std::pair<int, char>> vec_copy = oper_pvec;

        auto op = oper_pvec.begin();
        while (oper_pvec.size() != 0)
        {
            op = oper_pvec.begin();
            ++pos; //position of loop
            int key = std::get<0>(*op); //gets first value from vector pair
            char val = std::get<1>(*op); //gets second value from vector pair


            //gets previous/next vector pairs
            std::vector<std::pair<int, char>>::iterator prev_op = oper_pvec.begin();
            std::vector<std::pair<int, char>>::iterator next_op = oper_pvec.end();

            if (op != oper_pvec.begin()) prev_op = std::prev(op);
            if (op != oper_pvec.end()) next_op = std::next(op);


            //extracts the value of pairs
            if (pos > 0)
            {
                loper_pos = std::get<0>(*prev_op);
                loper = std::get<1>(*prev_op);
            }
            if (op == oper_pvec.begin()) loper_pos = 0;

            if (oper_pvec.size() == 1) roper_pos = input.length();          
            else
            {
                roper_pos = std::get<0>(*next_op);
                roper = std::get<1>(*next_op);
            }


            //replaces numbers and etc with product, only multiplication for now
            switch (val)
            {
                case 'x':
                {
                    int lnum_start = loper_pos + 1;
                    if (lnum_start == 1) lnum_start = 0;

                    if (loper_pos > 0)
                        if (isdigit(input[loper_pos - 1])) lnum_start = 0;

                    int lnum_len = key - (loper_pos + 1);
                    if (lnum_start == 0)
                    {
                        if (key == 1) lnum_len = 1;
                        else lnum_len = key - 1;
                    }
                    lnum = std::stod(input.substr(lnum_start, lnum_len));

                    int rnum_start = key + 1;
                    int rnum_len = (roper_pos - 1) - key;
                    rnum = std::stod(input.substr(rnum_start, rnum_len));

                    double prod = lnum * rnum;
                    std::string to_string = std::to_string(prod);
                    input.replace(loper_pos, roper_pos, to_string);
                    break;
                }
            }

            //clears the vector and then finds the operators again
            oper_pvec.clear();
            int vpos = 0;
            for (std::string::iterator it = input.begin(); it != input.end(); ++vpos, ++it)
            {
                if (vpos == input.length())
                {
                    vpos = 0;
                    break;
                }
                switch (*it)
                {
                    case 'x':
                    {
                        oper_pvec.push_back(std::pair<int, char>(vpos, 'x'));
                        break;
                    }
                    case '/':
                    {
                        oper_pvec.push_back(std::pair<int, char>(vpos, '/'));
                        break;
                    }
                    case '+':
                    {
                        oper_pvec.push_back(std::pair<int, char>(vpos, '+'));
                        break;
                    }
                    case '-':
                    {
                        oper_pvec.push_back(std::pair<int, char>(vpos, '-'));
                        break;
                    }
                }
            }
        }
        //converts to double then prints on screen
        double out = std::stod(input);
        std::cout << out << std::endl;
    }
}