Класс Calculator

Рубрика: C++, Дата: 11 March, 2013, Автор:
Tags:

Определите класс Calculator так, чтобы большая часть его реализации состаяла из функции (параграф 6 Страуструп). Создайте калькуляторы и активизируйте их для ввода из cin, из командной строки, для ввода строк программы. Реализуйте вывод в разные приемники.

Да опять нифига не ясно чо куда. Но будем потихоньку разбираться. Но у меня, то есть готовая программа, щас ее попытаюсь оформить в виде класса, а затем попробую просто инициализировать класс, либо несколько классов.

Короче половину задачи сделал оформил в виде класса.

Файл Calculator.h:

//opredelenie Calculator
#ifndef CALCULATOR_H
#define CALCULATOR_H
#include <iostream>
using std::endl;
using std::cout;
using std::cin;
using std::cerr;
#include <string>
using std::string;
#include <map>
using std::map;
#include <cctype>
using std::isalpha;
#include <cstdlib>
using std::exit;
enum Token_value//тип данных
{
	NAME, NUMBER, END,
	PLUS='+',MINUS='-',MUL='*',DIV='/',
	PRINT=';',ASSIGN='=',LP='(',RP=')'
};

//самый последний возврат из функции get_token() хранится в этой переменной
Token_value curr_tok=PRINT;
double number_value;//хранит последнее прочитаное NUMBER
string string_value;
int no_of_errors;//количество ошибок
map<string,double>table;

class Calculator
{

public:
	//обрабатывает сложение и вычитание
	double expr(bool get);//clojenie i vuchitanie
	//Обработка умножения и деления
	double term(bool get);//ymnojenie i delenie
	//обрабатывает первичные выражения
	double prim(bool get);//obrabotka pervichnux vurajenii
	//синтаксический анализатор
	Token_value get_token();
	//обработка ошибок
	double error(const string& s);

};

#endif

Файл Calculator.cpp:

//opredelenie functions Calculator
#include <iostream>
using std::endl;
using std::cout;
using std::cin;
using std::cerr;
#include <string>
using std::string;
#include <map>
using std::map;
#include <cctype>
using std::isalpha;
#include <cstdlib>
using std::exit;

#include "Calculator.h"

//обрабатывает сложение и вычитание
double Calculator::expr(bool get)//clojenie i vuchitanie
{
	double left=term(get);//обработка умножения и деления
	
	for(;;)//"vechno"
		switch(curr_tok)
		{
			case PLUS:
				left+=term(true);//
				break;
			case MINUS:
				left-=term(true);
				break;
			default:
				return left;
		}
}

//Обработка умножения и деления
double Calculator::term(bool get)//ymnojenie i delenie
{
	double left=prim(get);//обработка сложения и вычитания
	
	for(;;)
		switch(curr_tok)
		{
			case MUL:
				left*=prim(true);
				break;
			case DIV:
				if(double d=prim(true))
				{
					left/=d;
					break;
				}
				return error("divide by 0");
			default:
				return left;
		}
}

//обрабатывает первичные выражения
double Calculator::prim(bool get)//obrabotka pervichnux vurajenii
{
	if(get)get_token();
	
	switch(curr_tok)
	{
		case NUMBER:
		{
			double v=number_value;
			get_token();
			return v;
		}
		case NAME:
		{
			double& v=table[string_value];
			if(get_token()==ASSIGN) v=expr(true);
			return v;
		}
		case MINUS://ynarnui minyc
			return -prim(true);
		case LP:
		{
			double e=expr(true);
			if(curr_tok!=RP) return error("')' expected");
			get_token();//propyctit6 ')'
			return e;
		}
		default:
			return error("primary expected");
	}
}

//синтаксический анализатор
Token_value Calculator::get_token()
{
	char ch=0;
	do//propyctit6 vce probel6nue cimvolu krome '\n'
	{
		if(!cin.get(ch)) return curr_tok=END;
	}while(ch!='\n'&&isspace(ch));
	
	//cin >>ch;
	
	switch(ch)
	{
		case 0:
			return curr_tok=END;//нет символов выход
		case ';':
		case '\n':
			return curr_tok=PRINT;//
		case '*':
		case '/':
		case '+':
		case '-':
		case '(':
		case ')':
		case '=':
			return curr_tok=Token_value(ch);//операция
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
		case '.':
			cin.putback(ch);//назад в поток вставить
			cin >>number_value;//считать полностью
			return curr_tok=NUMBER;//возвратить число
		default://NAME,NAME=,ili owibka
			if(isalpha(ch))
			{
				string_value=ch;
				while(cin.get(ch)&&isalnum(ch)) string_value.push_back(ch);
				cin.putback(ch);
				return curr_tok=NAME;
			}
			error("bad token");
			return curr_tok=PRINT;
	}
}

//обработка ошибок
double Calculator::error(const string& s)
{
	no_of_errors++;
	cerr <<"error: "<<s<<'\n';
	return 1;
}

и сама main():

//draiver klacca Calculator
#include <iostream>

#include "Calculator.h"

int main()
{
	Calculator a;
	table["pi"]=3.1415926535897932385;//vvodim predopredelennue imena
	table["e"]=2.7182818284590452354;
	
	while(cin)
	{
		a.get_token();
		if(curr_tok==END)break;
		if(curr_tok==PRINT)continue;
			cout <<a.expr(false)<<'\n';
	}
	
	return no_of_errors;
	
	return 0;
}

Да не все я сделал здесь токо читает из cin ну и фиг сним, нету ввода из командной строки, и просто из строки. Ну вообще нету ввода из строки было б из строки, то можно б было и из командной строки сделать и из cin. Так что так фиг сним. Вообще это код запутаный, небольшой код, а такой запутаный. Видно, что профессионал писал, не такой как я. Я новичок мне его не понять. Не сильно я то понимаю, что куда идет.

Проще построить калькулятор на классе для простых арифметических выражений: http://www.kselax.ru/2013/03/klass-dlya-prostyx-arifmeticheskix-vyrazhenij/

 

  • Knyazhe

    А как к этому классу добавить перегрузку ввода/вывода >><< (что бы программа принимала строку с арифметическим выражением, а выводила итог), а то я испробовал разные варианты, и ни в какую?

rss