I'm writing a program that should read equations from a txt file and fill them in a linked-list, check their validity and then convert each valid equation to post-fix notation and calculate the final result. Then write them to a file or print them on the console depends on the user choice. Following is what I've already done, I know my code is really long but I posted it all in order to make my question more clear:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct node *ptr;
struct node
{
char eq[100];
char pstfix[100];
double result;
ptr next;
int topPST;
int topOP;
int validity;
};
typedef ptr list;
typedef ptr position;
list l;
void menu(); // prints the menu
void readFile(list l); //reads data from a file
int opPriority(char operators[],char operation,int top) ; // check the priority of a given operation
void isValid(position p);//Function to check the validity of each equation.
void convert(list l); // to convert from infix to postfix
void getResult(list l); // to calculate the result of an equation
double calculate(char operation, int op1,int op2);//To return the value in each step when getting the result
void showValidity(list l); // print the equations and show the ones that have errors
void acceptEq(list l); // Let the user enter equations on the console screen
void fillInfix(position p, char c[]);//A function to fill the array of infix in the node.
int isNum(char val);//returns if the value passed to it is a number or character.
void writeToFile(list l);//Write to the file
void showConsole(list l);//Show the final results on the console
int main()
{
printf("\t\t\t*Data Structure\tSecond project*\n\n\t\t\t*Convert from infix to postfix*\n\n");
menu();
l=(list)malloc(sizeof(struct node));
return 0;
}
//Function to print the menu and let the program work depending on the choice.
void menu()
{
system("cls");
int choice;
printf("\t\t\t\tMenu\n\n\t\t\t1.Read equations from file.\n\t\t\t2.Check validity.\n\t\t\t3.Convert to postfix.\n\t\t\t4.Add more equations to the file.\n\t\t\t\n\t\t\t5.Calculate Results.\n\t\t\t6.Write results to file.\n\t\t\t7.Show results on the console.\n\t\t\t8.End.\n\n\t\t\tEnter Your choice number please\n\t\t\t");
scanf("%d",&choice);
switch (choice)
{
case 1: readFile(l);
break;
case 2: isValid(l);
break;
case 3: convert(l);
break;
case 4: acceptEq(l);
break;
case 5: getResult(l);
break;
case 6: writeToFile(l);
break;
case 7: showConsole(l);
break;
case 8: exit(0);
}
}
//The following function should read equations from a file specified by the user
void readFile(list l)
{
system("cls");
char fileName[50];
FILE *eqFile;
printf("\t\t\tEnter the title of the file please\n\t\t\t");
scanf("\t\t\t%s",fileName);
eqFile=fopen(fileName,"r");
//To ensure the existence of the requested file.
while (eqFile == NULL)
{
printf("\t\t\tThe file you asked for does not exist. Enter another name or enter 'back' to return to menu\n\t\t\t");
scanf("\t\t\t%s",fileName);
if(strcmp(fileName,"back")==0) menu();
else eqFile=fopen(fileName,"r");
}
(l)->next=(position)malloc(sizeof (struct node));
position temp=(l)->next;
char line[100];
while (temp != NULL){
while (fgets(line,sizeof line, eqFile) != NULL)
{
isValid(temp);
if ((temp)->validity) fillInfix(temp,line);
temp=(temp)->next;
(temp)->next=NULL;
}
}
fclose(eqFile);
int choice;
printf("\t\t\tData Read Successfully\n\t\t\tEnter 0 to exit or 1 to return to menu\n\t\t\t");
scanf("%d",&choice);
if (choice) menu();
else exit(0);
}
void isValid(list l)
{
system("cls");
position temp;
temp=l;
int i,count=0;
while((temp)->next!=NULL)
{
for (i=0;i<100;i++)
{
if (((l)->eq[i]=='+' && (l)->eq[i+1]=='*') || ((l)->eq[i]=='-' && (l)->eq[i+1]=='*')|| ((l)->eq[i]=='*' && (l)->eq[i+1]=='/') || ((l)->eq[i]=='/' && (l)->eq[i+1]=='+')|| ((l)->eq[i]=='/' && (l)->eq[i+1]=='-') || (l)->eq[i]==' ')
count++;
}
if (count!=0) (temp)->validity=0;
temp=(temp)->next;
}
int choice;
printf("\t\t\tChecking validity is done enter 0 to quite or 1 to return to menu\n\t\t\t");
scanf("%d",&choice);
if(choice) menu();
else exit(0);
}
void fillInfix(position p, char line[])
{
int i;
for (i=0;i<100;i++)
{
while (line[i]!='\0')
{
(p)->eq[i]=line[i];
}
}
}
void push(char st[],char element, int top)
{
++top;
st[top]=element;
}
char pop(char st[],int top)
{
char elemnt=st[top];
--top;
return elemnt;
}
int opPriority(char operators[], char operation, int top)
{
if ((operation=='*' && operators[top]=='-') || (operation=='*' && operators[top]=='+') || (operation=='*' && operators[top]=='/') || (operation=='/' && operators[top]=='-')|| (operation=='/' && operators[top]=='+') || (operation=='+' && operators[top]=='-')) return 0;
else
if ((operation=='(' && operators[top]=='*') || (operation=='(' && operators[top]=='/') || (operation=='(' && operators[top]=='+') || (operation=='(' && operators[top]=='-')) return 0;
else if (operation==')') return 2;
else
return 1;
}
int isNum(char val)
{
if (val!='+' && val!='-' && val!='*' && val!='/') return 1;
else return 0;
}
void convert(list l)
{
position temp=l;
int i;
char operators[100];
while ((temp)->next != NULL)
{
temp=(temp)->next;
if ((temp)->validity)
{
for (i=0;i<100;i++)
{
if (isNum((temp)->eq[i])) push((temp)->pstfix,(temp)->eq[i],(temp)->topPST);
else
{
int priority=opPriority(operators,(temp)->eq[i],(temp)->topOP);
if (priority==1)
{
push((temp)->pstfix,pop(operators,(temp)->topOP),(temp)->topPST);
push(operators,(temp)->eq[i],(temp)->topOP);
}
else
if (priority ==0) push(operators,(temp)->eq[i],(temp)->topOP);
else
if (priority==2)
{
while (operators[(temp)->topOP]!='(')
{
push((temp)->pstfix,pop(operators,(temp)->topOP),(temp)->topPST);
}
char trash=pop(operators,(temp)->topOP);//Unwanted closed bracket
}
}
}
}
}
int choice;
printf("\t\t\tConversion Done successfully. Enter 0 to quite or 1 to return to menu\n\t\t\t");
scanf("%d",&choice);
if(choice) menu();
else exit(0);
}
void acceptEq(list l)
{
system("cls");
char newEq[100];
printf("\t\t\t Enter your equation please. Note that your equation must not exceed the 100 characters length.\n\t\t\t");
scanf("\t\t\t%s",newEq);
position temp=l;
position p=(position)malloc(sizeof (struct node));
while ((temp)->next!=NULL)
{
temp=(temp)->next;
}
(temp)->next=p;
isValid(p);
if ((p)->validity)
{
fillInfix(p,newEq);
convert(p);
}
}
void getResult(list l)
{
system("cls");
position temp=l;
while ((temp)->next != NULL)
{
temp=(temp)->next;
int i=0;
while ((temp)->pstfix[i]!= '\0')
{
if ((temp)->pstfix[i]=='+' || (temp)->pstfix[i]=='-' || (temp)->pstfix[i]=='*' || (temp)->pstfix[i]=='/')
(temp)->result = calculate((temp)->pstfix[i],(temp)->pstfix[i-2],(temp)->pstfix[i-1]);
push((temp)->pstfix,(temp)->result,(temp)->topPST);
printf("\n\t\t\t%c",(temp)->pstfix[i]);
i++;
}
printf("=%f",(temp)->result);
}
}
double calculate (char operation,int op1,int op2)
{
double result;
if (operation=='+') result=op1+op2;
if (operation=='-') result=op1-op2;
if (operation=='*') result=op1*op2;
if (operation=='/') result=op1/op2;
return result;
}
void writeToFile(list l)
{
system("cls");
char fileWName[50];
printf("\n\t\t\tEnter the name of the file you want to print on please\n\t\t\t");
scanf("\t\t\t%s",fileWName);
FILE* resultFile;
resultFile=fopen(fileWName,"w");
position temp=l;
fprintf(resultFile,"Infix Notation:\t\t");
fprintf(resultFile,"Validity:\t\t");
fprintf(resultFile,"Postfix Notation:\t\t");
fprintf(resultFile,"Value:\t\t\n");
while ((temp)->next != NULL)
{
temp=(temp)->next;
int i=0;
while ((temp)->eq[i]!='/0')
{
fprintf(resultFile,"%c",(temp)->eq[i]);
i++;
}
fprintf(resultFile,"\t\t");
i=0;
while ((temp)->pstfix[i]!='/0')
{
fprintf(resultFile,"%c",(temp)->pstfix[i]);
i++;
}
fprintf(resultFile,"\t\t");
if ((temp)->validity == 0) fprintf(resultFile,"INVALID");
else
{
fprintf(resultFile,"VALID\t\t");
fprintf(resultFile,"%f",(temp)->result);
}
}
fclose(resultFile);
int choice;
printf("\t\t\tDATA WRITTEN TO FILE SUCCESSFULLY. Press 1 to return to menu or 0 to quite\n\t\t\t");
scanf("%d",&choice);
if (choice) menu(l);
else exit(0);
}
void showConsole(list l)
{
system("cls");
position temp=l;
printf("Infix Notation:\t\t");
printf("Validity:\t\t");
printf("Postfix Notation:\t\t");
printf("Value:\t\t\n");
while ((temp)->next != NULL)
{
temp=(temp)->next;
int i=0;
while ((temp)->eq[i]!='/0')
{
printf("%c",(temp)->eq[i]);
i++;
}
printf("\t\t");
i=0;
while ((temp)->pstfix[i]!='/0')
{
printf("%c",(temp)->pstfix[i]);
i++;
}
printf("\t\t");
if ((temp)->validity == 0) printf("INVALID");
else
{
printf("VALID\t\t");
printf("%f",(temp)->result);
}
}
int choice;
printf("\t\t\tDATA WRITTEN SUCCESSFULLY. Press 1 to return to menu or 0 to quite\n\t\t\t");
scanf("%d",&choice);
if (choice) menu();
else exit(0);
}
I've already used debugger to find out where my problem is. And now I know that there's a compiling error in this statement:
(l)->next=(position)malloc(sizeof (struct node));
I'm wondering what's wrong with this statement? I'm trying to allocate space for a node in order to be able to create more nodes for each line (equation).