473,396 Members | 1,785 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

mathemathecal expression

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[i][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;
}

Jul 22 '05 #1
5 1362
"stanlo" <mu******@yahoo.com> wrote in message
news:11*********************@z14g2000cwz.googlegro ups.com...
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
As I said in my other reply, start with *one* thing at a time.
Don't try to do it all at once.
and what ever i do there is an
error.
So what is the error, and where does the compiler say it is?
However, i also think my program is too long
It might or might not be. What *is* a problem is that
it's hardly readable. Use indentation and whitespace
to organize your code. Remember that source code is
primarily for *humans* to read.
and so if someone
has written a shorter one i will be grateful.here is the program.
#include <string.h>
Why don't you use the std::string type instead of struggling
with the error-prone, difficult-for-beginners 'C-style'
strings (arrays of characters)?

#include <iostream.h>


This is not, nor has it ever been, a standard C++ header.
The correct header for declaring the standard stream
objects (std::cin, std::cout, etc.) is <iostream>.
No '.h'.

I won't even try to decipher the 'spaghetti' you've posted,
but repeat again: Start Small. One Thing At A Time.

BTW which C++ book(s) are you reading? There are far more
bad ones than good ones available (and unfortunately often
the 'bad' ones are used in shcools). Perhaps that's at least
part of your troubles.
-Mike
Jul 22 '05 #2
stanlo wrote:

<snip>

Whoa there Tex!
Examine this rewrite of 'doTask':

<code>

long evaluate(long op1, long op2, char op)
{
long result = 0;
switch (op)
{
case '*':
{
result = op1 * op2;
break;
}
case '/':
{
if (op2==0)
{
errorOutput(DivByZero);
result = 0;
}
else
{
result = op1 / op2;
}
break;
}
case '%':
{
// Whatever '%' was going to do. Modulus?
// You had this falling thru to 'm'. Intended?
// 'm' and '%' synonomous?
break;
}
case 'm':
{
if (op2==0)
{
cerr << DivByZero << endl;
result = 0;
}
else
{
result = op1 % op2;
}
break;
}
case '+':
{
result = op1 + op2;
break;
}
case '-':
{
result = op1 - op2;
break;
}
case '^':
{
result = polyno(op1,op2);
break;
}
case 'e':
{
result = op1*polyno(10,op2);
break;
}
default :
{
result = 0;
break;
}
}
return result;
}

<end code>

( Please no style wars, folks - exaggerated for clarity )

Notes:

- function name more reflective of purpose, self documenting.
- whitespace/indent is your friend.
- well named identifier for return value, self documenting.
- single point of 'return' at end.
- generous use of 'break'.
- easier to pick up missed brackets and semicolons.
- flow control now much more obvious.

This is now a much more debuggable, maintainable, comprehendible,
extensible, tolerable ... it might even work! :-)

You seem to have the basic idea of the project's requirements, and
reading your code I can sense ( and only sense, because of the spaghetti
) that you intuitively know what you're doing.
Good!
Now you have to express that, so

- someone else.
- yourself.
- your future self.
- the compiler

can all be aligned.

Also write, test and evaluate code in small bytes ( pun intended ).
Brick by brick.

There's a heap of other stuff I could probably discuss( eg. why
don't you store your error messages as standard library string types not
char arrays? Heck, you even nearly included the right header! ), but
'nuf for now. I do hope this helps. :-)

--

Cheers
--
Hewson::Mike
"This letter is longer than usual because I lack the time to make it
shorter" - Blaise Pascal
Jul 22 '05 #3
hello, i tried use the std and it did not work, so i saw .h in a
book and i tried and it worked.

Jul 22 '05 #4
thank u mike i will make a more readible text and post.

Jul 22 '05 #5

Mike Hewson wrote:i am reay very grateul or your reply, in fact your
proposition made me nderstood more what i was doing.i think u are right
too about the storing o my error messges.but i don t understand the
altenative u gave me,that is not to use char array, but use standard
libary types. well i make my program better in a moment and post it.
stanlo wrote:

<snip>

Whoa there Tex!
Examine this rewrite of 'doTask':

<code>

long evaluate(long op1, long op2, char op)
{
long result = 0;
switch (op)
{
case '*':
{
result = op1 * op2;
break;
}
case '/':
{
if (op2==0)
{
errorOutput(DivByZero);
result = 0;
}
else
{
result = op1 / op2;
}
break;
}
case '%':
{
// Whatever '%' was going to do. Modulus?
// You had this falling thru to 'm'. Intended?
// 'm' and '%' synonomous?
break;
}
case 'm':
{
if (op2==0)
{
cerr << DivByZero << endl;
result = 0;
}
else
{
result = op1 % op2;
}
break;
}
case '+':
{
result = op1 + op2;
break;
}
case '-':
{
result = op1 - op2;
break;
}
case '^':
{
result = polyno(op1,op2);
break;
}
case 'e':
{
result = op1*polyno(10,op2);
break;
}
default :
{
result = 0;
break;
}
}
return result;
}

<end code>

( Please no style wars, folks - exaggerated for clarity )

Notes:

- function name more reflective of purpose, self documenting.
- whitespace/indent is your friend.
- well named identifier for return value, self documenting.
- single point of 'return' at end.
- generous use of 'break'.
- easier to pick up missed brackets and semicolons.
- flow control now much more obvious.

This is now a much more debuggable, maintainable, comprehendible, extensible, tolerable ... it might even work! :-)

You seem to have the basic idea of the project's requirements, and reading your code I can sense ( and only sense, because of the spaghetti ) that you intuitively know what you're doing.
Good!
Now you have to express that, so

- someone else.
- yourself.
- your future self.
- the compiler

can all be aligned.

Also write, test and evaluate code in small bytes ( pun intended ). Brick by brick.

There's a heap of other stuff I could probably discuss( eg. why
don't you store your error messages as standard library string types not char arrays? Heck, you even nearly included the right header! ), but
'nuf for now. I do hope this helps. :-)

--

Cheers
--
Hewson::Mike
"This letter is longer than usual because I lack the time to make it
shorter" - Blaise Pascal


Jul 22 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

23
by: Paul Rubin | last post by:
OK, I want to scan a file for lines matching a certain regexp. I'd like to use an assignment expression, like for line in file: if (g := re.match(pat, line)): croggle(g.group(1)) Since...
70
by: Roy Yao | last post by:
Does it mean "(sizeof(int))* (p)" or "sizeof( (int)(*p) )" ? According to my analysis, operator sizeof, (type) and * have the same precedence, and they combine from right to left. Then this...
22
by: Tony Johansson | last post by:
Hello Experts! I'm reading i a book about C++ and they mention infix with telling what it is. I hope you out there can do so. Many thanks! //Tony
2
by: Mike Turco | last post by:
I like using the expression builder for a lot of different things but it isn't always available when I want to use it, for example in the code window, or in all of the control properties. I am...
14
by: John Temples | last post by:
Given this code: extern volatile unsigned char v; int main(void) { v; return 0; }
15
by: Nerox | last post by:
Hi, If i write: #include <stdio.h> int foo(int); int main(void){ int a = 3; foo(a); }
7
by: Billa | last post by:
Hi, I am replaceing a big string using different regular expressions (see some example at the end of the message). The problem is whenever I apply a "replace" it makes a new copy of string and I...
28
by: Marc Gravell | last post by:
In Linq, you can apparently get a meaningful body from and expression's .ToString(); random question - does anybody know if linq also includes a parser? It just seemed it might be a handy way to...
18
by: dspfun | last post by:
Hi! The words "expression" and "statement" are often used in C99 and C- textbooks, however, I am not sure of the clear defintion of these words with respect to C. Can somebody provide a sharp...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.