S
stanlo
hello, i thought it was wise to include my program. my main problem is
i wantto adapt the program to do only multiplication
,division,addition, and subtraction and what ever i do there is an
error.However, i also think my program is too long and so if someone
has written a shorter one i will be grateful.here is the program.
#include <string.h>
#include <iostream.h>
namespace
{
const int maxLength = 82; // including end character and the zero
character
const char finishLoopChar = '$';
// Input and error atlets
const char AnExpr[] = "Please give An Expression,and then press the
ENTER key:";
const char Answer[] = " The Answer is: ";
const char DivByZero[] = "WARNING!!!:No Division by Zero;Check
answer.";
const char FloatPtNo[] = "WARNING!!!:No decimal points
allowed,discarded,please Watch out for Answer.";
const char ExpNeg[] = " Negative exp is not allowed,Watch out for
answer";
const char wrongSyntax[] = "WARNING!!!:Wrong syntax,please review
input and Watch out for answer!";
//operations and Levels of operation
const operatorLevels = 4; // including exponents and mod(not asked,but
derived from discussion with friends)
const opsPerLevel = 2; // Two operations with same precidence on
same level
const char operatorTable[operatorLevels][opsPerLevel] = {{'e', '^'},
{'*','/'}, {'%','m'}, {'+','-'} };
//Function declarations
long polyno(long base, long exp);
bool searchOperator(char* line, char &curOp, int &curOpPos);
long doTask(long operand1, long operand2, char operation);
bool verArray(const char array[operatorLevels][opsPerLevel], char
testChar);
int goToOp1(char* line, int startPos, int &curExprBegin);
int goToOp2(char* line, int startPos, int &curExprEnd);
void shortArray(char* line, int curExprBegin, int curExprEnd, long
number);
void discardBadChar(char* line, bool &exit);
void errorOutput(const char* erroralert);
//Function definitions
int length(long number) //how long is the number
{
int i=0;
int answer=0;
if (number <= 0 ) {
answer=1;
number *= -1;
}
while (number >= polyno(10,i)) i++;
return answer + i;
}
void errorOutput(const char* errorAlert) //write error alerts
{
cerr << errorAlert << endl;
}
bool verArray(const char array[operatorLevels][opsPerLevel], char
testChar) //Check if char "test" is in array
{
int i=0;
int j=0;
while (i < operatorLevels) {
if (array[j]==testChar) return true;
j++;
if (j == opsPerLevel) {
j=0;
i++;
}
}
return false;
}
//Function definitions
long doTask(long operand1, long operand2, char operation) //evaluation
of operations
{
switch (operation) {
case '*': return operand1 * operand2;
case '/': if (operand2==0) {
errorOutput(DivByZero);
return 0;
}
else return operand1 / operand2;
case '%':
case 'm': if (operand2==0) {
cerr << DivByZero << endl;
return 0;
}
else return operand1 % operand2;
case '+': return operand1 + operand2;
case '-': return operand1 - operand2;
case '^': return polyno(operand1,operand2);
case 'e': return operand1*polyno(10,operand2);
default : return 0;
}
}
long polyno(long base, long exp) //Calculate powers
{
if (exp < 0) errorOutput(ExpNeg); //Prevent floating point answers
long answer = 1;
while (exp > 0) {
exp--;
answer = answer * base;
}
return answer;
}
//Function definitions: string processing
int goToOp1(char* line, int startPos, int &curExprBegin) //Detect left
operant
{
int pos=startPos-2;
int op1Size=0;
int answer;
answer = 0;
//Construct operand until another operator or begin of line reached
while ((pos>=0) && (verArray(operatorTable, line[pos])==false)) {
answer = answer + (line[pos] - '0') * polyno(10,op1Size);
op1Size++;
pos--;
}
if ((line[pos]=='-') && ((verArray(operatorTable, line[pos-1])) ||
(pos==0))) { //Detect negative sign
answer*=-1;
pos--;
}
curExprBegin = pos + 1;
return answer;
}
int goToOp2(char* line, int startPos, int &curExprEnd) //Detect right
operant
{
int pos=startPos;
int answer=0;
int factor=1;
if (line[startPos]=='-') { //Detect negative operand
factor=-1;
pos++;
}
//Construct operand until another operator or end of line reached
while ((line[pos]!='\0') && (verArray(operatorTable,
line[pos])==false)) {
answer = answer * 10 + line[pos] - '0';
pos++;
}
curExprEnd = pos - 1;
return answer*factor;
}
//Overwrite operand1, operator and operand2 by calculation result,
shorten line
void shortArray(char* line, int curExprBegin, int curExprEnd, long
number)
{
char newLine[maxLength];
int oldLinePos=0, newLinePos=0;
while (line[oldLinePos]!='\0') {
if (((oldLinePos < curExprBegin) || (oldLinePos > curExprEnd))) {
newLine[newLinePos]=line[oldLinePos]; //Simple copy from line to
newLine
newLinePos++;
}
else { //Inserting intermediate result number
if (number <0) {
newLine[newLinePos]='-';
newLinePos++;
number*=-1;
}
{ //Block for variable tmpAnswer being valid only in this area
int tmpAnswer;
for (int i=length(number)-1; i>=0 ; i--) {
tmpAnswer = number / polyno(10,i);
number -= polyno(10,i) * tmpAnswer;
newLine[newLinePos] = tmpAnswer + '0';
newLinePos++;
}
}
oldLinePos = curExprEnd;
}
oldLinePos++;
}
newLine[newLinePos]='\0'; //Append null character
strcpy(line,newLine);
}
void discardUnwantedChar(char* line, bool &exit) //Remove invalid
characters
{
int readPos=0;
int insertPos=0;
char lastChar=' ';
while (line[readPos]!='\0') {
if (readPos!=0 && verArray(operatorTable, lastChar) &&
verArray(operatorTable, line[readPos]) && line[readPos] != '-') {
//Check for double operator except *-, +-, --,...
errorOutput(wrongSyntax);
}
else if(((line[readPos]>='0') && (line[readPos]<='9')) ||
(verArray(operatorTable, line[readPos])==true)) {
line[insertPos]=line[readPos];
insertPos++;
}
else {
switch(line[readPos]) {
case ',' :
case '.' : errorOutput(FloatPtNo);
break;
case 'T' : //Transform to lowercase
case 'L' : line[insertPos] = line[readPos] - 'A' + 'a';
insertPos++;
break;
case finishLoopChar : exit = true;
break;
}
}
lastChar = line[readPos];
readPos++;
}
line[insertPos]='\0';
if (verArray(operatorTable, line[0]) && line[0] != '-')
errorOutput(wrongSyntax); //Check for leading operator
if (verArray(operatorTable, line[insertPos-1]))
errorOutput(wrongSyntax); //Check for operator at end of line
}
bool searchOperator(char* line, char &curOp, int &curOpPos)
{
bool answer=false;
int curOpLevel=0;
curOp = ' ';
while ((curOpLevel<operatorLevels) && (answer == false)) { //Check all
operator levels
curOpPos=0;
while ((line[curOpPos] != '\0' ) && (answer == false)) { //Search line
for current operator
if (line[curOpPos]==operatorTable[curOpLevel][0]) {
answer = true;
curOp=operatorTable[curOpLevel][0];
}
else if ((line[curOpPos]==operatorTable[curOpLevel][1]) &&
(curOpPos!=0)) {
answer = true;
curOp=operatorTable[curOpLevel][1];
}
curOpPos++;
}
curOpLevel++;
}
return answer;
}
} //closing unnamed namespace
int main()
{
char line[maxLength];
bool opFound = false;
int curOpPos=0;
char curOp=' ';
int curExprBegin=0, curExprEnd=0;
long operand1, operand2;
bool exit = false;
cout << finishLoopChar << endl; //User friendly opening
while (exit == false) {
cout << AnExpr << endl;
cin.getline(line, sizeof(line)); //Reads maximum maxlength-1
characters and adds \0
discardUnwantedChar(line, exit); //Discard invalid characters from
line
opFound=searchOperator(line, curOp, curOpPos); //Search line for
operator,and keep answer in variable opFound
while (opFound==true) {
operand1=goToOp1(line, curOpPos, curExprBegin); //go to operant 1
operand2=goToOp2(line, curOpPos, curExprEnd); //go to operant 2
shortArray(line, curExprBegin, curExprEnd, doTask(operand1, operand2,
curOp)); //shorten line
opFound=searchOperator(line, curOp, curOpPos); //Search for more
operators
}
cout << Answer << line << endl; //Output answer
}
return 0;
}
i wantto adapt the program to do only multiplication
,division,addition, and subtraction and what ever i do there is an
error.However, i also think my program is too long and so if someone
has written a shorter one i will be grateful.here is the program.
#include <string.h>
#include <iostream.h>
namespace
{
const int maxLength = 82; // including end character and the zero
character
const char finishLoopChar = '$';
// Input and error atlets
const char AnExpr[] = "Please give An Expression,and then press the
ENTER key:";
const char Answer[] = " The Answer is: ";
const char DivByZero[] = "WARNING!!!:No Division by Zero;Check
answer.";
const char FloatPtNo[] = "WARNING!!!:No decimal points
allowed,discarded,please Watch out for Answer.";
const char ExpNeg[] = " Negative exp is not allowed,Watch out for
answer";
const char wrongSyntax[] = "WARNING!!!:Wrong syntax,please review
input and Watch out for answer!";
//operations and Levels of operation
const operatorLevels = 4; // including exponents and mod(not asked,but
derived from discussion with friends)
const opsPerLevel = 2; // Two operations with same precidence on
same level
const char operatorTable[operatorLevels][opsPerLevel] = {{'e', '^'},
{'*','/'}, {'%','m'}, {'+','-'} };
//Function declarations
long polyno(long base, long exp);
bool searchOperator(char* line, char &curOp, int &curOpPos);
long doTask(long operand1, long operand2, char operation);
bool verArray(const char array[operatorLevels][opsPerLevel], char
testChar);
int goToOp1(char* line, int startPos, int &curExprBegin);
int goToOp2(char* line, int startPos, int &curExprEnd);
void shortArray(char* line, int curExprBegin, int curExprEnd, long
number);
void discardBadChar(char* line, bool &exit);
void errorOutput(const char* erroralert);
//Function definitions
int length(long number) //how long is the number
{
int i=0;
int answer=0;
if (number <= 0 ) {
answer=1;
number *= -1;
}
while (number >= polyno(10,i)) i++;
return answer + i;
}
void errorOutput(const char* errorAlert) //write error alerts
{
cerr << errorAlert << endl;
}
bool verArray(const char array[operatorLevels][opsPerLevel], char
testChar) //Check if char "test" is in array
{
int i=0;
int j=0;
while (i < operatorLevels) {
if (array[j]==testChar) return true;
j++;
if (j == opsPerLevel) {
j=0;
i++;
}
}
return false;
}
//Function definitions
long doTask(long operand1, long operand2, char operation) //evaluation
of operations
{
switch (operation) {
case '*': return operand1 * operand2;
case '/': if (operand2==0) {
errorOutput(DivByZero);
return 0;
}
else return operand1 / operand2;
case '%':
case 'm': if (operand2==0) {
cerr << DivByZero << endl;
return 0;
}
else return operand1 % operand2;
case '+': return operand1 + operand2;
case '-': return operand1 - operand2;
case '^': return polyno(operand1,operand2);
case 'e': return operand1*polyno(10,operand2);
default : return 0;
}
}
long polyno(long base, long exp) //Calculate powers
{
if (exp < 0) errorOutput(ExpNeg); //Prevent floating point answers
long answer = 1;
while (exp > 0) {
exp--;
answer = answer * base;
}
return answer;
}
//Function definitions: string processing
int goToOp1(char* line, int startPos, int &curExprBegin) //Detect left
operant
{
int pos=startPos-2;
int op1Size=0;
int answer;
answer = 0;
//Construct operand until another operator or begin of line reached
while ((pos>=0) && (verArray(operatorTable, line[pos])==false)) {
answer = answer + (line[pos] - '0') * polyno(10,op1Size);
op1Size++;
pos--;
}
if ((line[pos]=='-') && ((verArray(operatorTable, line[pos-1])) ||
(pos==0))) { //Detect negative sign
answer*=-1;
pos--;
}
curExprBegin = pos + 1;
return answer;
}
int goToOp2(char* line, int startPos, int &curExprEnd) //Detect right
operant
{
int pos=startPos;
int answer=0;
int factor=1;
if (line[startPos]=='-') { //Detect negative operand
factor=-1;
pos++;
}
//Construct operand until another operator or end of line reached
while ((line[pos]!='\0') && (verArray(operatorTable,
line[pos])==false)) {
answer = answer * 10 + line[pos] - '0';
pos++;
}
curExprEnd = pos - 1;
return answer*factor;
}
//Overwrite operand1, operator and operand2 by calculation result,
shorten line
void shortArray(char* line, int curExprBegin, int curExprEnd, long
number)
{
char newLine[maxLength];
int oldLinePos=0, newLinePos=0;
while (line[oldLinePos]!='\0') {
if (((oldLinePos < curExprBegin) || (oldLinePos > curExprEnd))) {
newLine[newLinePos]=line[oldLinePos]; //Simple copy from line to
newLine
newLinePos++;
}
else { //Inserting intermediate result number
if (number <0) {
newLine[newLinePos]='-';
newLinePos++;
number*=-1;
}
{ //Block for variable tmpAnswer being valid only in this area
int tmpAnswer;
for (int i=length(number)-1; i>=0 ; i--) {
tmpAnswer = number / polyno(10,i);
number -= polyno(10,i) * tmpAnswer;
newLine[newLinePos] = tmpAnswer + '0';
newLinePos++;
}
}
oldLinePos = curExprEnd;
}
oldLinePos++;
}
newLine[newLinePos]='\0'; //Append null character
strcpy(line,newLine);
}
void discardUnwantedChar(char* line, bool &exit) //Remove invalid
characters
{
int readPos=0;
int insertPos=0;
char lastChar=' ';
while (line[readPos]!='\0') {
if (readPos!=0 && verArray(operatorTable, lastChar) &&
verArray(operatorTable, line[readPos]) && line[readPos] != '-') {
//Check for double operator except *-, +-, --,...
errorOutput(wrongSyntax);
}
else if(((line[readPos]>='0') && (line[readPos]<='9')) ||
(verArray(operatorTable, line[readPos])==true)) {
line[insertPos]=line[readPos];
insertPos++;
}
else {
switch(line[readPos]) {
case ',' :
case '.' : errorOutput(FloatPtNo);
break;
case 'T' : //Transform to lowercase
case 'L' : line[insertPos] = line[readPos] - 'A' + 'a';
insertPos++;
break;
case finishLoopChar : exit = true;
break;
}
}
lastChar = line[readPos];
readPos++;
}
line[insertPos]='\0';
if (verArray(operatorTable, line[0]) && line[0] != '-')
errorOutput(wrongSyntax); //Check for leading operator
if (verArray(operatorTable, line[insertPos-1]))
errorOutput(wrongSyntax); //Check for operator at end of line
}
bool searchOperator(char* line, char &curOp, int &curOpPos)
{
bool answer=false;
int curOpLevel=0;
curOp = ' ';
while ((curOpLevel<operatorLevels) && (answer == false)) { //Check all
operator levels
curOpPos=0;
while ((line[curOpPos] != '\0' ) && (answer == false)) { //Search line
for current operator
if (line[curOpPos]==operatorTable[curOpLevel][0]) {
answer = true;
curOp=operatorTable[curOpLevel][0];
}
else if ((line[curOpPos]==operatorTable[curOpLevel][1]) &&
(curOpPos!=0)) {
answer = true;
curOp=operatorTable[curOpLevel][1];
}
curOpPos++;
}
curOpLevel++;
}
return answer;
}
} //closing unnamed namespace
int main()
{
char line[maxLength];
bool opFound = false;
int curOpPos=0;
char curOp=' ';
int curExprBegin=0, curExprEnd=0;
long operand1, operand2;
bool exit = false;
cout << finishLoopChar << endl; //User friendly opening
while (exit == false) {
cout << AnExpr << endl;
cin.getline(line, sizeof(line)); //Reads maximum maxlength-1
characters and adds \0
discardUnwantedChar(line, exit); //Discard invalid characters from
line
opFound=searchOperator(line, curOp, curOpPos); //Search line for
operator,and keep answer in variable opFound
while (opFound==true) {
operand1=goToOp1(line, curOpPos, curExprBegin); //go to operant 1
operand2=goToOp2(line, curOpPos, curExprEnd); //go to operant 2
shortArray(line, curExprBegin, curExprEnd, doTask(operand1, operand2,
curOp)); //shorten line
opFound=searchOperator(line, curOp, curOpPos); //Search for more
operators
}
cout << Answer << line << endl; //Output answer
}
return 0;
}