2014 dxdy logo

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

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




Начать новую тему Эта тема закрыта, вы не можете редактировать и оставлять сообщения в ней.
 
 vector subscript out of range
Сообщение17.10.2009, 16:25 


12/12/08
7
Не могу понять, в чем дело. Я, наверное, тупой, но даже не могу найти дебаггером место, где это происходит. Весь день мучил сегодня этот калькулятор, и башка уже не варит. Помогите, а?

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

На 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 сообщение ] 

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group