//implement a calculator
//no bracket
#include <iostream>
#include<cctype>//the 'isdigit' which was included in it will be used in the funcion named number;
#include <cstdlib>
using std::cin;
using std::cout;
using std::endl;
void eatspaces(char * str);
double number(const char * str, size_t & index);
double expr(const char *str);
double term(const char *str, size_t & index);
int main()
{
const int max{ 80 };//length of the expression
char buffer[max]{};
cout << endl << "enter an expression , or an empty line to quit :" << endl;
while (1)
{
cin.getline(buffer, sizeof buffer);//get an expression from keyboard
cout << "the expression you enter is : " << buffer<<endl;
eatspaces(buffer);
cout << "the expression without spaces is : " << buffer << endl;
double value{};
//size_t index{};
value = expr(buffer);//calculate the expression
//value = number(buffer, index);//be use to test whether the function "number" is on work
cout << "the value :" << value << endl;
if (buffer[0] == 0)
return 0;
}
//cout << endl;
return 0;
}
/*expr :calculate the expression got from buffer*/
double expr(const char *str)
{
double value{};
size_t index{};//this index will be used from now to the end ,which show as a '&'
//divide the expression into term according to the '+' or '-'
value=term(str, index);//the beginning term
for (;;)
{
char temp{ *(str + index) };
index++;
cout << "test index" << endl;
switch (temp)
{
case '\0':return value;
case '+': value = value + term(str, index); break;//whether put index++ here or not?
case '-':value = value - term(str, index); break;
//default:char message[38]{ "expression evaluation error,found: " };
// strncat_s(message, str + index -1, 1);
// throw message;
// break;
}
}
}
/*calculate every term by using the multi (*)and divide(/)*/
double term(const char *str, size_t & index)
{
double value{};
value = number(str, index);
while (1)
{
if (*(str + index) == '*')
value = value*number(str, ++index);
else if (*(str + index) == '/')
value = value / number(str, ++index);
else
break;
//switch (*(str + index++))
//{
//case '\0':return value;
//case '*':value = value*number(str, index); break;
//case '/':value = value / number(str, index); break;
//default:return value;
//}
}
return value;
}
/*read number;*/
double number(const char * str, size_t & index)
{
double value{};
while (isdigit(*(str + index)))
{
value = 10 * value + (*(str + index) - '0');
index++;
}
if (*(str + index) != '.')
{
return value;//if the number is not a decimal
}
else
{
//if the number is a decimal
double factor{ 1.0 };
index++;//point to the char after the dicimal
while (isdigit(*(str + index)))
{
factor = factor*0.1;
value = value + (*(str + index) - '0')*factor;
index++;
}
return value;
}
}
/*delete space*/
void eatspaces(char * str)
{
size_t i{};//control the pointer which point to the new string;
size_t j{};//control the pointer which point to the old string;
do
{
if (*(str + j) != ' ')
{
*(str + i) = *(str + j);
i++;
}
j++;
} while (*(str + j) != '\0');
*(str + i) = '\0';//give an end command to the new string ;
return;
}