2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




 
 vector subscript out of range
Сообщение17.10.2009, 16:25 
Не могу понять, в чем дело. Я, наверное, тупой, но даже не могу найти дебаггером место, где это происходит. Весь день мучил сегодня этот калькулятор, и башка уже не варит. Помогите, а?

Это консольный калькулятор. Вводишь выражение, он его должен считать.

На convertToDouble не ругайтесь, про strtod() узнал только сейчас, потом изменю.

код: [ скачать ] [ спрятать ]
Используется синтаксис C++
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <string>
#include <windows.h>
using namespace std;

class Element
//a class to store both numbers and operators
{
private:
        double number;
        char operat;
public:
        //constructor for number
        Element(double num)
        {
                number = num;
                operat = '\0';
        }
        //constructor for operator
        Element(char oper)
        {
                operat = oper;
                number = 0;
        }
        //get value functions
        double getNumber()
        {
                return number;
        }
        char getOperator()
        {
                return operat;
        }
        //set value functions
        //do i need them?
        //do i add oper = '/0'?
        void setNumber(double num)
        {
                number = num;
        }
        void setOperator(char oper)
        {
                operat = oper;
        }
};

void errorHandling(int errorCode)
{
        switch(errorCode)
        {
        case 0:
                cout<<"Unknown error. Program terminates"<<endl;
                break;
        case 1:
                cout<<"Input contains unsupported symbols. Program terminates"<<endl;
                break;
        case 2:
                cout<<"Missing left bracket"<<endl;
                break;
        case 3:
                cout<<"Missing right bracket"<<endl;
                break;
        case 4:
                cout<<"Can't divide by zero"<<endl;
                break;
        /**/
        }
}

bool checkSupport(string str)
//a function to check for unsupported symbols
{
        int strLength = str.length();
        int i;
        for (i=0; i <= strLength - 1; i++)
        {
                //if there are only numbers and supported symbols then continue
                if(str[i]>='0'&&str[i]<='9')
                        continue;
                else if(str[i]=='+'||str[i]=='-'||str[i]=='*'||str[i]=='/'||str[i]=='.'||str[i]=='('||str[i]==')'||str[i]=='=')
                        continue;
                //if not, then there are unsupported symbols
                else
                        return false;
        }
        return true;
}




vector<Element>::iterator intAsIterator(vector<Element> &expression, int num)
//making the vector iteration easier
{
        int i;
        vector<Element>::iterator it = expression.begin();

        for(i = 1; i <= num; i++)
                it++;
        return it;
}

double convertToDouble(string str)
{
        int strLength = str.length();
        int pointP = strLength;
        int i;
        double convertedNum = 0;
        double intPart = 1, fracPart = 0.1;

        for(i=0; i <= strLength - 1; i++)
        {
                if(str[i]=='.')
                {
                        pointP = i;
                        break;
                }
        }

        for(i = pointP - 1; i>=0; i--)
        {
                convertedNum += (double)(str[i]-'0') * intPart;
                intPart *= 10;
        }
        for(i = pointP + 1; i <= strLength; i++)
        {
                convertedNum += (double)(str[i] - '0') * fracPart;
                fracPart /= 10;
        }
        return convertedNum;
}


bool calculate(vector<Element> &expression, int i)
{
        double result = 0;
        //the calculating part itself
        if(expression[i].getOperator()=='+')
                result = expression[i-1].getNumber() + expression[i+1].getNumber();
        else if (expression[i].getOperator()=='-')
                result = expression[i-1].getNumber() - expression[i+1].getNumber();
        else if (expression[i].getOperator()=='*')
                result = expression[i-1].getNumber() * expression[i+1].getNumber();
        else if (expression[i].getOperator()=='/')
                result = expression[i-1].getNumber() / expression[i+1].getNumber();

        Element tempElem(result);
       
        //cleaning up the mess
        expression.erase(intAsIterator(expression, i));
        expression.insert(intAsIterator(expression, i), tempElem);
        expression.erase(intAsIterator(expression, i+1));
        expression.erase(intAsIterator(expression, i-1));

        return true;
}


bool determineOperatorPrecedanceAndCalculate(vector<Element> &expression, int leftP, int rightP)
//multiplication and division first, addition and substraction second
{
        int i;

        //multiplication and division calculation
        for(i = leftP; i <= rightP; i++)
        {
                if(expression[i].getOperator()=='*')
                {
                        calculate(expression, i);
                        //only a number left instead of two numbers and an operator, changing right position
                        rightP -= 2;
                        i--;
                }
                else if(expression[i].getOperator()=='/')
                {
                        //checking division by zero
                        if(expression[i+1].getNumber()==0)
                        {
                                errorHandling(4);
                                return false;
                        }
                        calculate(expression, i);
                        //same as above
                        rightP -= 2;
                        i--;
                }
        }
        //addition and substraction calculation
        for (i = leftP; i <= rightP; i++)
        {
                if(expression[i].getOperator()=='+'||expression[i].getOperator()=='-')
                {
                        calculate(expression, i);
                        //same as above
                        rightP -= 2;
                        i--;
                }
        }
        return true;
}



bool simplifyAndCalculate(vector<Element> &expression)
//a function to remove parantheses by calculating their contents and simplyfying the total expression
{
        int size = expression.size();
        int leftP, rightP;
        int i, j;
        leftP = 0;
        rightP = size;
       
        //hunting for parentheses, looking for the first to appear right one
        for(i = 0; i<size; i++)
        {
                if(expression[i].getOperator()==')')
                {
                        rightP = i;
                        //and then the corresponding left one
                        for(j = i; j>=-1; j--)
                        {
                                if(j==-1)
                                {
                                        errorHandling(2);
                                        return false;
                                }
                                if(expression[j].getOperator()=='(')
                                {
                                        leftP = j;
                                        break;
                                }
                        }
                        //removing the right brace first
                        expression.erase(intAsIterator(expression, rightP));
                        expression.erase(intAsIterator(expression, leftP));

                        if(!(determineOperatorPrecedanceAndCalculate(expression, leftP, rightP-2)))
                                return false;
                        //deleting the calculated fragment
                        size -= (rightP - leftP);
                        i = 0;
                }
        }
        //if there is no right brace but a left brace, then error
        for(i = 0; i <= size - 1; i++)
        {
                if(expression[i].getOperator()=='(')
                {
                        errorHandling(3);
                        return false;
                }
        }
        //no more parentheses from this point
        if((size!=1)&&(determineOperatorPrecedanceAndCalculate(expression, 0, size - 1) == false))
                return false;
        return true;
}




                               
int main()
{
        //self-explanatory
        SetConsoleTitle(TEXT("My Console Calculator"));

        //variables, vector container to store the expression
        string inputStr, oneNumberStr;
        vector<Element> expression;
        int leftP, rightP;
        int strLength = inputStr.length();
        int i;
        double convertedNum;

        //welcome text
        cout<<"This is a simple console calculator.\nAddition, substraction, multiplication, division, floating point numbers and parentheses are supported.\nType in you expression without spaces or 'exit' to exit:"<<endl;
       
        while(cin>>inputStr)
        {      
                //exit case
                if(inputStr=="exit")
                        return 0;      

                //unsupported symbol checking
                if(checkSupport(inputStr)==false)
                {
                        errorHandling(1);
                        return 0;
                }

                //adding an element to the expression
                for(i=0; i <= strLength - 1; i++)
                {
                        //adding an operator
                        if(!((inputStr[i]>='0'&&inputStr[i]<='9')||inputStr[i]=='.'))
                        {
                                Element elem(inputStr[i]);
                                expression.push_back(elem);
                                continue;
                        }
                        //adding a number
                        if((inputStr[i]>='0'&&inputStr[i]<='9')||inputStr[i]=='.')
                        {
                                leftP = i;
                                i++;
                                for(;; i++)
                                {
                                        //if there is an operator to the right of the number then break
                                        if(!((inputStr[i]>='0'&&inputStr[i]<='9')||inputStr[i]=='.'))
                                        {
                                                rightP = i;
                                                i--;
                                                break;
                                        }
                                        //if it's the end of the expression then break
                                        if(i==strLength-1)
                                        {
                                                rightP = strLength;
                                                break;
                                        }
                                }
                                oneNumberStr = inputStr.substr(leftP, rightP - leftP);
                                convertedNum = convertToDouble(oneNumberStr);
                                Element elem(convertedNum);
                                expression.push_back(elem);
                        }
                }
                vector<Element>::iterator iter = expression.end() - 1;
                expression.erase(iter);

                //and just a bit more code

                if(simplifyAndCalculate(expression)==true)
                        cout<<"The result is "<<expression[0].getNumber()<<endl;
                else
                        errorHandling(0);
        }
        return 0;
}
 


-- Сб окт 17, 2009 21:50:44 --

решил проблему. сам дурак. такие дела надо на несколько дней растягивать, а не 8 часов за монитором сидеть.

извините плиз, тему можно удалить

 
 
 [ 1 сообщение ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group