Thread: Help on Detecting Errors in Mathematical Equations

  1. #1
    and Nothing Else Matters
    Join Date
    Jul 2006
    Location
    Philippines
    Posts
    117

    Unhappy Help on Detecting Errors in Mathematical Equations

    After several hours of brainstorming, it would seem i cannot solve this on my own, so i am humbly asking the experts here for some expert help (and if possible, some code snippets)

    My problem is this:
    1) User is asked to input a mathematical expression in INFIX form (the normal way).
    2) My program then checks the expression for any syntax errors. (im stuck here for now).
    3) It then converts it to postfix (or Reverse Polish Notation), then evaluates it.

    examples of erroneous expressions are:

    5 ( 5 + 5) 5 (no operation between parenthesis)
    5 5 + 5 (5 5 is treated as two different numbers due to white space between)
    5 + + 5 (double addition operation without operands)
    + 5 + 5 + (insufficient operands)
    ) 5 + 5 (invalid parenthesis placement)
    ( ( 5 + 5) (parenthesis mismatch)
    ...... other errors which you guys know but i havent figured out yet.

    so far, i think i've solved the mismatched parenthesis problem. the rest seems too difficult for me.
    i know how to do 3), but 2) seems to elude my wits. can anyone help me? this is what i've accomplished so far:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <conio.h>
    #include <string.h>
    #include <ctype.h>
    #define MAX 20
    
    typedef struct stackA {
    	char *token;
       stackA *next;
    } stack;
    
    typedef *stack stack_ptr;
    
    int errorCheck(char *input);
    char *output(char *input);
    int evaluate(char *output);
    char *pop(stack_ptr S);
    void push(char *c, stack_ptr S);
    int isOperator(char c);
    
    int main(void) {
    	char input[MAX], *output, try_again;
    	int choice, error, answer;
    	do {
    		clrscr();
    		error=0;
    		puts("Enter the infix notation:");
    		fgets(input,sizeof(input),stdin); /* to prevent buffer overflow*/
    		error=errorCheck(input);
    		if(error != 0)
    			puts("You have enterred an erroneous equation!");
    		else {
    			output=convert(input);
    			printf("\nConverted to postfix: %s",output);
    			answer=evaluate(output);
    		   printf("\nThe answer to the equation %s is: %d",input,answer);
    		}
    		puts("\nDo you wish to try again? \(type \"N\" to quit, any other to repeat\)");
    		try_again=getchar();\
    	} while(!(try_again == 'N' || try_again == 'n'));
    	getch();
    }
    
    int errorCheck(char *input) {
    	int i, len, found_error=0,Lparenthesis=0,Rparenthesis=0,digit=0,operator_start=0, operator_end=0;
    	len=strlen(input);
    	for(i=0;i<len && found_error==0;i++) {
    		while(isspace(input[i]))
    			i++;
    		if(input[i] == '(')
    			Lparenthesis++;
    		else if(input[i] == ')') {
    			if(Lparenthesis == 0)
    				found_error=1;
    			else Rparenthesis++;
    		}
    		if(isdigit(input[i])) {
    			digit=1;
    			while(isdigit(input[i]))
    				i++;
    			while(isspace(input[i]))
    				i++;
    			if(isdigit(input[i]) || input[i] == '(' || input[i] == ')')
    				found_error=1;
    			else digit=0;
    		}
    	}
    }
    note) the program isnt finished yet, but if I separate the errorCheck function and convert it into a program, it compiles, but the expression (5 + 5) is reported as having errors. i tried to trace the sequence of the program but to no avail, i just couldnt see the problem.

    thanks in advance!
    It is not who I am inside but what I do that defines me.

  2. #2
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    Have you considered adjusting your order of operations? Error checking an infix expression is vastly simpler if you do it while converting to postfix rather than as a separate task.
    My best code is written with the delete key.

  3. #3
    Devil's Advocate SlyMaelstrom's Avatar
    Join Date
    May 2004
    Location
    Out of scope
    Posts
    4,079
    examples of erroneous expressions are:

    5 ( 5 + 5) 5 (no operation between parenthesis)
    Where I come from, that's generally implied as multiplication, but I understand your examples.

    Here's the facts... write your algorithm to convert to post-fix... somewhere in the middle of this your perfectly good algorithm is going to get stuck (It's going to look for a closing parenthesis and not find it, it's going to look for an operator and not find it, etc). This is where I would do error checking. At this point, you can simply output that there was an error in calculation and end it or you can delve deeper and try to figure out the error, it's up to you.

    Now, before I finish, I want to make one thing clear. Just because here I say just do the algorithm and error check when an error occurs doesn't mean this is how all error checking should be handled in programming. It's worth noting the distinction between a logical error and a run-time error. A logical error you can identify as it happens and fix accordingly. A run-time error will crash your program before you get a chance to fix it. You'll want to do error checking on all potential run-time errors before the error has a chance to occur.

    That's my opinion on that. There are plenty more experience programmers that may say different, so if they do, I'd be interested in hearing their logic, too.
    Sent from my iPadŽ

  4. #4
    and Nothing Else Matters
    Join Date
    Jul 2006
    Location
    Philippines
    Posts
    117
    Hmmm, i'll consider it. i have the pseudocode for converting to postfix, and it's already too complicated for me. If i add the error detection in an otherwise already complicated code, im afraid i wont understand it anymore hehehe!!

    but just out of curiousity, how would you do it (no code necessary)?? i will paste the pseudocode for converting to postfix later since i am running late for my class for today. thanks!
    It is not who I am inside but what I do that defines me.

  5. #5
    Devil's Advocate SlyMaelstrom's Avatar
    Join Date
    May 2004
    Location
    Out of scope
    Posts
    4,079
    Quote Originally Posted by sangken
    but just out of curiousity, how would you do it (no code necessary)??
    It involved using a stack, normally... Check this link out.
    http://www.qiksearch.com/articles/cs/infix-postfix/
    Sent from my iPadŽ

  6. #6
    and Nothing Else Matters
    Join Date
    Jul 2006
    Location
    Philippines
    Posts
    117
    Quote Originally Posted by SlyMaelstrom
    Where I come from, that's generally implied as multiplication, but I understand your examples.
    it's the same where i come from too. but if i allow that, im afraid i do not know how to handle such exceptions (in programming), yet. so i generalized that between operands, there should be operators, and '(' or ')' are not considered as operands in this program only.
    It is not who I am inside but what I do that defines me.

  7. #7
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >If i add the error detection in an otherwise already complicated code, im afraid i wont
    >understand it anymore hehehe!!
    The conversion algorithm is straightforward and (to me) extremely simple. If you found it somewhere, chances are good that it lacks any error checking at all, which is a very bad thing. By adding the error checking, you're killing two birds with one stone: completing another task in your list and making your code more robust.
    My best code is written with the delete key.

  8. #8
    and Nothing Else Matters
    Join Date
    Jul 2006
    Location
    Philippines
    Posts
    117
    Quote Originally Posted by SlyMaelstrom
    It involved using a stack, normally... Check this link out.
    http://www.qiksearch.com/articles/cs/infix-postfix/
    what i meant was how would you guys do error checking while converting at the same time.
    It is not who I am inside but what I do that defines me.

  9. #9
    and Nothing Else Matters
    Join Date
    Jul 2006
    Location
    Philippines
    Posts
    117
    My professor gave us this project without requiring error checking at all, and only using single digits for operands. But i want to do error checking because good programs should be able to handle user input errors right? and what kind of calculator only accepts single digits? LOL. but darn, it's not as easy as i thought it would be.
    It is not who I am inside but what I do that defines me.

  10. #10
    Devil's Advocate SlyMaelstrom's Avatar
    Join Date
    May 2004
    Location
    Out of scope
    Posts
    4,079
    Well, that's all up to you... personally, I would just keep trucking along until my algorithm can't figure out what to you based on it's logic... basically the "default" case on a switch statement or the "else" on an if statement. Of course, the first few times this happened, I would track the error to make sure it was in fact a logical error on the input. As for reporting with errors when they happen... basically, if your conversion logic is correct, when the error is encountered it should be pretty obvious what is missing (You'll know what precedence you're looking for, or what kind of symbol is missing). You just have to look at what you got and assess the problem with one of many predefined error messages. That's how I'd do it.
    Sent from my iPadŽ

  11. #11
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >but darn, it's not as easy as i thought it would be.
    Programming is hard. Welcome to reality.
    My best code is written with the delete key.

  12. #12
    and Nothing Else Matters
    Join Date
    Jul 2006
    Location
    Philippines
    Posts
    117
    Quote Originally Posted by Prelude
    >but darn, it's not as easy as i thought it would be.
    Programming is hard. Welcome to reality.
    yeah, thanks for opening my eyes... hmm, tis not yet too late to "shift" to an "easier" course, like, say, NURSING. LOL...

    but anyways, i'll give the adding-the-error-checking-during-the-conversion idea a try. if i cant handle it, i'll ask you guys again for some "concrete" help. and if i still cant do it, then darn, i guess i'll just die another day.
    It is not who I am inside but what I do that defines me.

  13. #13
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >tis not yet too late to "shift" to an "easier" course, like, say, NURSING.
    Nursing is hard too. Maybe something more like this?

    >if i cant handle it, i'll ask you guys again for some "concrete" help.


    >and if i still cant do it,
    Then I would be very surprised. This forum has very sharp minds, very talented programmers, and excellent teachers. Sometimes all three rolled up into one.
    My best code is written with the delete key.

  14. #14
    and Nothing Else Matters
    Join Date
    Jul 2006
    Location
    Philippines
    Posts
    117
    Just one last question though, in my above code snippet, specifically in the errorCheck() function, why does the equation (5+5) register as having errors? i traced the program cleanly and according to my analysis, it shouldnt. i know im missing something here but i just dont know what.

    here's the function, i converted it into a single program for testing purposes:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <conio.h>
    #include <string.h>
    #include <ctype.h>
    
    int main(void) {
    	int i, len, found_error=0,Lparenthesis=0,Rparenthesis=0,digit=0,operator_start=0, operator_end=0;
    	char input[20];
    	clrscr();
    	puts("Enter:");
    	gets(input);
    	len=strlen(input);
    	for(i=0;i<len && found_error==0;i++) {
    		while(isspace(input[i]))
    			i++;
    		if(input[i] == '(')
    			Lparenthesis++;
    		else if(input[i] == ')') {
    			if(Lparenthesis == 0)
    				found_error=1;
    			else Rparenthesis++;
    		}
    		if(isdigit(input[i])) {
    			digit=1;
    			while(isdigit(input[i]))
    				i++;
    			while(isspace(input[i]))
    				i++;
    			if((isdigit(input[i]) || input[i] == '(') && digit==1)
    				found_error=1;
    			else digit=0;
    		}
    	}
    	if((Lparenthesis-Rparenthesis) != 0)
    		found_error=1;
    	if(found_error==1)
    		puts("Error found");
    	else puts("No errors!");
    	getch();
    }
    It is not who I am inside but what I do that defines me.

  15. #15
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    You aren't recognizing the closing paren. When doing a lot of index work inside of the loop, you shouldn't include an increment step at the end as it usually causes problems:
    Code:
    for ( i = 0; i < len && found_error == 0; ) {
      /* Make all changes to i in the body */
    }
    My best code is written with the delete key.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Ten Errors
    By AverageSoftware in forum Contests Board
    Replies: 0
    Last Post: 07-20-2007, 10:50 AM
  2. detecting errors with the compiler
    By InvariantLoop in forum C++ Programming
    Replies: 6
    Last Post: 04-22-2004, 09:55 PM
  3. Manipulation and analysis of Mathematical Equations
    By WebmasterMattD in forum C++ Programming
    Replies: 13
    Last Post: 06-07-2003, 10:08 PM
  4. Mathematical equations
    By EvBladeRunnervE in forum Game Programming
    Replies: 12
    Last Post: 04-02-2003, 04:14 PM
  5. Detecting Math Errors
    By Davros in forum C++ Programming
    Replies: 7
    Last Post: 03-06-2003, 03:41 PM