making me some calculator

ive posted on this in the past but i had some time earlier and i basically rewrote this whole program and have some questions. the calculator functions by letting the user enter an expression like:
3+2-15*3

and it will give the result following the order of operations. to make it work i could just add '*' and '/' possibilities in my switch statement, but then it would just work from left to right, it wouldnt follow the order of operations. anyone have advice on how i might go about adding functionality for these two following PEMDAS? thanks!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include <iostream>
#include <cctype>
using std::cout;
using std::endl;
using std::cin;
void eatspaces(char* str);
int addNumbers(char* str);
int number(char* str, int& index);

int main(void)
{
	char str[15];
	cin.getline(str, 15, '\n');
	eatspaces(str);

	int sum = addNumbers(str);

	cout << "Total is " << sum << endl;

	return 0;
}

void eatspaces(char* str)
{
	int i = 0;
	int j = 0;

	while((*(str + i) = *(str + j++)) != '\0')
		if (*(str + i) != ' ')
			i++;
	return;
}

int number(char* str, int& index)
{
	int number = 0;
	while(isdigit(*(str + index)))
	{
		number *= 10;
		number += (*(str + index)) - '0';
		index++;
	}

	cout << number << endl;
	return number;
}

int addNumbers(char* str)
{
	int index = 0;
	int total = 0;
	
	total += number(str, index);
	for(;;)
	{
		switch(*(str + index))
		{
		case '+':
			index++;
			total += number(str, index);
			break;
		case '-':
			index++;
			total -= number(str, index);
			break;
		case '\0':
			return total;
		default:
			cout << "ERROR AT POSITION " << index << endl << "ABORTING" << endl;
			exit(1);
		}
	}

	return total;
}

You are probably looking to use:
Have the find in a if statement.
dont really see how thats going to help getting the order of operations to work. please expand ;)
Using if statements:

if (Find "(" && Find ")") // Code
if (Find "^") // Code
if (Find "*" || Find "/") // Code
if (Find "+" || Find "-") // Code


Etc. That is not the syntax. I haven't used find yet but it will work, just read up on it.

If it finds "*" for example then make a code inside the if statement getting the number to the left and to the right of the found position. Then call your MultFunc();
Last edited on
ive used the find function before and it isnt very useful in this situation. there needs to be a switch statement for the program to work.
Your reading the string one character at a time (i.e. from left to right.) Mathimatical expresions are not read that way. "2 + 3 * 5" is read as 3 * 5 first then 2 + that answer.

If you read the string from left to right you need to first check for (), then ^, then * and /, and then + and -. As you find operations replace the value there with the answer.
Example: 2 + 3 * (5 – 1)
After step 1: 2 + 3 * 4
After step 2: 2 + 12
After step 3: 14
Done.
Last edited on
ive thought of that but have had some troubles getting the values replaced, ill try again i guess
Last edited on
A simple solution is to write a recursive descent parser (or a Pratt parser, my favorite). Google them. You'll need to tokenize the input before parsing, though.
heres the latest build of it which now has decimals and im looking into recursive descent parsers :)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include <iostream>
#include <cctype>
using std::cout;
using std::endl;
using std::cin;
void eatspaces(char* str);
double addNumbers(char* str);
double number(char* str, int& index);
double decimal(char* str, int& index);

int main(void)
{
	char str[15];
	cout << "Calculator: " << endl
		<< "+ - add" << endl
		<< "- - substract" << endl
		<< "* - multiply" << endl
		<< "/ - divide" << endl << endl;
	
	char cont = 'y';
	//continue solving equations until they say to stop
	while (cont == 'y' || cont == 'Y')
	{
		cin.getline(str, 15, '\n');
		eatspaces(str);

		double sum = addNumbers(str);

		cout << "\t = " << sum << endl;
		
		cout << "Continue(Y/N)? ";
		cin >> cont;
		cin.ignore(1, '\n');
	}

	return 0;
}

void eatspaces(char* str)
{
	//remove all spaces from the string entered
	int i = 0;
	int j = 0;

	while((*(str + i) = *(str + j++)) != '\0')
		if (*(str + i) != ' ')
			i++;
	return;
}

double number(char* str, int& index)
{
	//get the value of the next number in the series and increment index to the next position
	double number = 0;
	while(isdigit(*(str + index)))
	{
			number *= 10;
			number += (*(str + index)) - '0';
			index++;
	}
	//if no decimal return the number
	if(*(str + index) != '.')
		return number;
	//if there is a decimal add it to the number and then return it
	else
		index++;
		return (number + decimal(str, index));
}

double decimal(char* str, int& index)
{
	//get the value of a decimal after the number if there is one
	double decimal = 0;
	double multiplier = .1;
	while(isdigit(*(str + index)))
	{
		decimal += (*(str + index) - '0') * multiplier;
		multiplier /= 10;
		index++;
	}

	return decimal;
}

double addNumbers(char* str)
{
	int index = 0;
	double total = 0;
	
	//get the value of the first term

	total += number(str, index);
	for(;;)
	{
		switch(*(str + index))
		{
		//run through each operaton and perform the needed operation to the total value
		case '+':
			index++;
			total += number(str, index);
			break;
		case '-':
			index++;
			total -= number(str, index);
			break;
		case '*':
			index++;
			total *= number(str, index);
			break;
		case '/':
			index++;
			total /= number(str, index);
			break;
		case '\0':
			//if at the end of the string return the total value
			return total;
		
		default:
			//if invalid input, show where the error occured and close the program
			cout << endl << endl;
			cout << "ERROR AT POSITION " << index << endl;
			cout << str << endl;
			for (; index > 0; index--)
				cout << " ";
			cout << "^";

			cout << endl;
			exit(1);
		}
	}

	return total;
}
Last edited on
Topic archived. No new replies allowed.