I have written this parsing algorithm in c++ and compiled in visual studio.On runtime after giving the value it gives an assertion error.
The logic is correct bcuz ive dry runned it but i think there's a problem with memory allocation.I need urgent help.Please.

// sas.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include<iostream>
#include<stdlib.h>
#include<string.h>
using namespace std;
const int LEN=80;
const int MAX=40;
//////////////////////////////////////////////////////////////////////////////
class Type
   {
   public:
   virtual float getnumber()=0;
   virtual char getoperator()=0;
   virtual int get()=0;
   };
/////////////////////////////////////////////////////////////////////////////
class Operator : public Type
   {
   private:
      char oper;
      int d; 
   public:
      Operator(char p,int y):oper(p),d(y){}
      char getoperator();
      float getnumber(){ return NULL; }
      int get(){return d;}
   };
char Operator::getoperator()
      {
          return oper;
          }
/////////////////////////////////////////////////////////////////////////////
class Number : public Type
   {
   private:
      float fnum;
      int d; 
   public:
      Number(float f,int y):fnum(f),d(y){}
      float getnumber();
      char getoperator(){ return NULL; }
      int get(){return d;}
   };
float Number::getnumber()
         {
         return fnum;
         }
//////////////////////////////////////////////////////////////////////////////
class Stack
    {
    private:
       Type* st[MAX];
       int top;
    public:
        Stack():top(0){}
       void push(Type* var)
        { st[++top]=var; }
       Type* pop()
            { return st[top--]; }
       int gettop()
            { return top; }
    };
//////////////////////////////////////////////////////////////////////////////
class express{
private:
    char*pstr;
    Stack s;
    Type* arr[80];
    int len;
public:
    express(char* ptr):pstr(ptr){
        len=static_cast<int>(strlen(ptr));}
    void parse();
    float solve();
};
void express::parse(){
    int i=0,x=0;
    char ch;
    while(i<len){
        if(ch>='0'&&ch<='9'){
            char* a;
            float f;
            int j=i;
            while(true){
                strcat_s(a,20,&ch);
                j++;
                ch=pstr[j];
                if(ch<'0'||ch>'9'){
                    f=static_cast<float>(atof(a));
                    i=j;
                    arr[x]=new Number(f,1);
                    break;
                }
            }
        }
        else{
            arr[x]=new Operator(ch,2);
            i++;
        }
        x++;
        }
        int d;
        for(int k=0;k<x;k++){
            d=arr[k]->get();
            if(d==1){
                s.push(arr[k]);
            }
            else{
                char ch2=arr[k]->getoperator();
                if(s.gettop()==1)
                    s.push(arr[k]);
                else{
                    float lastval;
                    char lastop;
                    Type* a1=s.pop();
                    lastval=a1->getnumber();
                    Type* a2=s.pop();
                    lastop=a2->getoperator();
                    delete a2;
                    delete a1;
                    if((ch2=='*'||ch2=='/')&&(lastop=='+'||lastop=='-')){
                        s.push(&Operator(lastop,2));
                        s.push(&Number(lastval,1));
                    }
                    else{
                        Type* a3=s.pop();
                        float val1=a3->getnumber();
                        switch(lastop){
                            case'+':
                                s.push(&Number((val1+lastval),1));break;
                            case'-':
                                s.push(&Number((val1-lastval),1));break;
                            case'*':
                                s.push(&Number((val1*lastval),1));break;
                            case'/':
                                s.push(&Number((val1/lastval),1));break;
                        }
                    }
                    s.push(arr[k]);
                }
            }
        }
    }
    float express::solve(){
        float v1,v2;
        char a3;
        while(s.gettop()>1){
            Type* n=s.pop();
            Type* m=s.pop();
            Type* o=s.pop();
            v1=n->getnumber();
            a3=m->getoperator();
            v2=o->getnumber();
            switch(a3){
                case'+':
                    s.push(&Number((v1+v2),1));break;
                case'-':
                    s.push(&Number((v1-v2),1));break;
                case'*':
                    s.push(&Number((v1*v2),1));break;
                case'/':
                    s.push(&Number((v1/v2),1));break;
            }
            delete o;
            delete m;
            delete n;
        }
        Type* x=s.pop();
        v1=x->getnumber();
        delete x;
        return v1;
    }
    void main(){
        char string[LEN];
        cout<<"Enter Expression: ";
        cin>>string;
        express* e=new express(string);
        e->parse();
        cout<<"The value is: ";
        cout<<e->solve();
    }

Recommended Answers

All 7 Replies

Please use code tags to make it easier to read.

Use int as the return type for main(). Even if your compiler lets you use void as the return type, it's better to use int.

Try to figure out where the problem is by commenting out all but the most basic part of the program. In addition to compiling, be sure the most basic part works when the program runs. Then add back one function/method at a time and add debugging code to be sure the function does what you think it does. Run the program and remove the debugging code when you're sure it works. Then add the next function back. Repeat until you find the part that's causing the assert problem at runtime. Then try to fix it yourself, and if you can't figure it out, post the pertinent information regarding the function/lines that cause the problem together with the input used to create the run time error and the expected outcome if it had worked correctly.

The error I got was that ch was being used without being initialized

It pointed to line 5 in this code:

void express::parse(){
	int i=0,x=0;
	char ch;
	while(i<len){
		if(ch>='0'&&ch<='9'){

Where it is obvious that you declared ch on line 3 but have not assigned a value.

What did your error message say?

(Did you bother to read it?)

1. You forgot that strcat works with c-strings i.e. char arrays with null byte at the end of contents:

void express::parse(){
int i=0,x=0;
char ch; // it's a single char, not char array
while(i<len) {
    if (ch >= '0' && ch <= '9') {
        char* a;
        float f;
        int j=i;
        while (true) { // strcat wants char arrays but...
            strcat_s(a,20,&ch); // *** !!! *** crash

2. The NULL macros is not zero: it's null pointer value (pointer to nowhere):

float getnumber(){ return NULL; } // must be 0.0
...
char getoperator(){ return NULL; } // must be '\0'

Thanks all u guys, by reading your replies i finally figured out the problems.Here's the correct code.I just want some one to check that it works fine on a microsoft compiler.

// sas.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include<iostream>
#include<stdlib.h>
#include<string.h>
const int LEN=80;
const int MAX=80;
class Type
   {
   public:
   virtual float getnumber()=0;
   virtual char getoperator()=0;
   virtual int get()=0;
   };
/////////////////////////////////////////////////////////////////////////////
class Operator : public Type
   {
   private:
      char oper;
      int d; 
   public:
      Operator(char p,int y):oper(p),d(y){}
      char getoperator();
      float getnumber(){ return 0.0; }
      int get(){return d;}
   };
char Operator::getoperator()
      {
          return oper;
          }
/////////////////////////////////////////////////////////////////////////////
class Number : public Type
   {
   private:
      float fnum;
      int d; 
   public:
      Number(float f,int y):fnum(f),d(y){}
      float getnumber();
      char getoperator(){ return '\0'; }
      int get(){return d;}
   };
float Number::getnumber()
         {
         return fnum;
         }
////////////////////////////////////////////////////////////////////////////////
char pstr[80];
size_t len;
Type* arr[20];
char ch;
char a[20];
char*pt;
size_t i=0;
int x=0;
int d;
float lastval;
char lastop;
float val1;
float df;
float v;
float v2;
char a2;
using namespace std;
class Stack
    {
    private:
       Type* st[MAX];
       int top;
    public:

        Stack():top(-1){}
       void push(Type* var)
        { 
            st[++top]=var; }
       Type* pop()
            { return st[top--]; }
       int gettop()
            { return top; }
    };
static Stack s;
//////////////////////////////////////////////////////////////////////////////
class express{  
public:
    express(char* ptr){
        strcpy(pstr,ptr);
        len=strlen(ptr);}
    void parse();
    float solve();
};
void express::parse(){
    while(i<len){
        ch=pstr[i];
        if((ch>='0'&&ch<='9')){
            float f;
            size_t j=i;
            while(true){
                pt=strcat(a,&ch);
                j++;
                ch=pstr[j];
                if((ch<'0'||ch>'9')&&ch!='.'){
                    f=static_cast<float>(atof(pt));
                    i=j;
                    arr[x]=new Number(f,1);
                    int m;
                    for(m=0;m<20;m++)
                        a[m]='\0';
                    break;
                }
            }
        }
else{
            arr[x]=new Operator(ch,2);
            i++;
        }
        x++;
        }
    for(int h=0;h<x;h++){
    if(arr[h]->get()==1)
    cout<<arr[h]->getnumber();
    else
        cout<<arr[h]->getoperator();
    cout<<endl;
}
        for(int k=0;k<x;k++){
            d=arr[k]->get();
            if(d==1)
                s.push(arr[k]);
            else{
                ch=arr[k]->getoperator();
                if(s.gettop()==0)
                    s.push(arr[k]);
                else if(ch=='-'||ch=='*'||ch=='/'||ch=='+'){
                    Type* a1=s.pop();
                    lastval=a1->getnumber();
                    Type* a2=s.pop();
                    lastop=a2->getoperator();
                    Type* a3;
                    if((ch=='*'||ch=='/')&&(lastop=='+'||lastop=='-')){
                        s.push(&Operator(lastop,2));
                        s.push(&Number(lastval,1));
                    }
                    else{
                        a3=s.pop();
                        val1=a3->getnumber();
                        switch(lastop){
                            case'+':
                                s.push(&Number((val1+lastval),1));break;
                            case'-':
                                s.push(&Number((val1-lastval),1));break;
                            case'*':
                                s.push(&Number((val1*lastval),1));break;
                            case'/':
                                s.push(&Number((val1/lastval),1));break;
                        }
                    }
                    s.push(arr[k]);
                }
            }
        }
    }
    float express::solve(){
          while(s.gettop()>=1){
            Type* n=s.pop();
            Type* m=s.pop();
            Type* o=s.pop();
            v2=n->getnumber();
            a2=m->getoperator();
            v=o->getnumber();
            switch(a2){
                case'+':
                    s.push(&Number((v+v2),1));break;
                case'-':
                    s.push(&Number((v-v2),1));break;
                case'*':
                    s.push(&Number((v*v2),1));break;
                case'/':
                    s.push(&Number((v/v2),1));break;
            }

        }
        Type* x1;
        x1=s.pop();
        df=x1->getnumber();
        return df;
    }
    void main(){
        char string[LEN];
        cout<<"Enter Expression: ";
        cin>>string;
        express* e=new express(string);
        e->parse();
        cout<<"The value is: ";
        cout<<e->solve();
        cout<<endl;
    }
commented: For ignoring ALL the code tags hints - have a cookie -5

Please, in the future, surround your posted code with code tags.
For C++ code they look like this:
[code=c++] // Your Code here

[/code]

My compiler complained about the #include "stdafx.h" because you didn't provide one. I removed the line and it compiled without errors.

There were two warnings on the use of strcpy() and strcat() as it is potentially unsafe. (There is no check to make sure you don't overflow the string you are copying or appending to.)

The first pointed me to an interesting construct, the Express constructor is copying to a global string?

// starting on line 50
char pstr[80];
size_t len;

// starting on line 85
class express{ 
public:
	express(char* ptr){
		strcpy(pstr,ptr);
		len=strlen(ptr);}
	void parse();
	float solve();
};

In fact, now that I look at it more, you have a list of global variables that seem to get used wherever they are 'needed'.

// starting on line 49
////////////////////////////////////////////////////////////////////////////////
char pstr[80];
size_t len;
Type* arr[20];
char ch;
char a[20];
char*pt;
size_t i=0;
int x=0;
int d;
float lastval;
char lastop;
float val1;
float df;
float v;
float v2;
char a2;
using namespace std;

From a design standpoint, you probably shouldn't be using global variables unless you can show that they need to be global.

I have for example no real issue with these:

const int LEN=80;
const int MAX=80;

But a comment as to what they are for would be nice. (Probably not essential on a one-off homework, but in code you might ever come back to, you'll probably appreciate the comments you leave yourself.)

Ok, back to globals for a second. char pstr[80]; which should probably be char pstr[LEN]; and size_t len; are only referenced from within methods of the express class. Why are they not data members of express?

Would you believe that if your class looked like:

class express{ 
	char pstr[LEN];
	size_t len;
public:
	express(char* ptr){
		strcpy(pstr,ptr);
		len=strlen(ptr);}
	void parse();
	float solve();
};

None of the rest of express would need to change and you would be using private class data instead of global data?

When I ran the program with "3+4" it seemed to parse ok.

Not having looked at the code, I passed it "4*(3-2*(7-4))" and the application faulted.

After I did, I looked at it and you don't appear to have any support for the '(' and ')' characters. (If your assignment didn't mention them, don't worry about it.)

Did your assignment mention vaildating the input?

Ok, it faulted on '3+4*5' too, and I think that should be fair game.

Maybe there's a little more to look at?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.