Array not being assigned char after certain number of loops - c

I am in the process of writing an infix to postfix function. After it loops through a couple of times(8 or 9th loop), my postfix array won't accept any more characters(it's set for 100).
void convertToPost(char infix[], char postfix[])
{
StackNode *pMem=NULL;
int i=-1,j=0, priority=0,priorityStack=0,operandCounter=0;
push(&pMem,'(');
infix[strlen(infix)]=')';
printf("%s\n",infix);
for(j=0;j<strlen(infix);j++)
{
putchar('\n');
printf("infix[%d]: %s\n",j,infix);
printf("postfix[%d]: %s\n",j,postfix);
putchar('\n');
if(infix[j] <= 57 && infix[j] >= 48)
{
i++;
postfix[i]=infix[j]; // not assigning value 8 to postfix
i++;
postfix[i] = ' ';
}
else if(infix[j] == '(')
{
push(&pMem,infix[j]);
//pop(&pMem);
}
else if(infix[j] == ')')
{
while(pMem->pNext != NULL)
{
if(pMem->pString == '(')
{
pop(&pMem);
}
else
{
postfix[i]= ' ';
i++;
postfix[i] = pMem->pString;
i++;
pop(&pMem);
}// figure out how to take char from top of stack and put in postfix something pop()
//push(&pMem,'(');
}
push(&pMem,'(');
//pop(&pMem);
}
else if(infix[j] == '+' || infix[j] == '-' || infix[j] == '^' || infix[j] == '*' || infix[j] == '/' || infix[j] == '%')
{
//i--;
if(operandCounter==0)
{
push(&pMem,infix[j]);
operandCounter++;
}
else
{
priority=Precedence(infix[j]);
priorityStack=Precedence(pMem->pString);//pString is empty
if(priority >= priorityStack)
{
if(pMem->pString != '(')
{
i++;
postfix[i]=pMem->pString;
i++;
postfix[i]=' ';
pop(&pMem);
push(&pMem,infix[j]);
}
else
{
push(&pMem,infix[j]);
}
}
}
}
}
}
This is the sample equation that I am using: 9*(5-4)+2/6
Its output should be: (9 5 4 - * 2 6 / +)
I put a comment where the problem occurs first. It continues throughout after it reaches that point. For example when I run the code it returns: 9 5 4 - *
But gives no error codes or anything.
If you would like some of the other functions (i.e priority, push, pop) feel free to ask.

inside the for loop(), strlen(infix) value is undefined. Because you are replacing the terminating NULL character in the string.infix[strlen(infix)]=')'; Which causes strlen() to return undefined value.
so change
infix[strlen(infix)]=')';
to
int len = strlen(infix);
infix[len]=')';
infix[len+1] = '\0';
Also make sure you have sufficient memory allocated for the array so the len+1 index in the array will not be out of bounds access.

Related

infix to postfix converstion in C with multiple digits input

What I'm trying to obtain is a calculator that will take infix notation, ignore insignificant whitespace characters like " " or '#', then convert that infix notaion into postfix notation and do simple calculations like addition, subtraction etc. So far the code is taking input in infix notation trimming it in a way that ignores insignificant whitespace characters and outputs the postfix notation.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>;
#include <ctype.h>;
#define MAX_LENGTH 100
//Functions
void push(char x);
char pop();
void trimString(char string[], char newString[]);
void inputToRPN(char trimmedExp[], char rpnExp[]);
int calculateRPN(char rpnExp[]);
char stack[MAX_LENGTH];
char resStack[MAX_LENGTH];
int top = -1;
int resTop = -1;
int index = 0;
int main() {
int res;
char exp[MAX_LENGTH] = "10 +2";
char trimmedExpression[MAX_LENGTH];
char rpnExpression[MAX_LENGTH];
// Input commented out as per suggestion in comments
//printf("Enter expression : ");
//fgets(exp, 100, stdin);
printf("Infix expression: %s \n", exp);
trimString(exp, trimmedExpression);
printf("\n");
inputToRPN(trimmedExpression, rpnExpression);
res = calculateRPN(rpnExpression);
//printf("Result of calculation: %d", res);
return 0;
}
void push(char x) {
stack[++top] = x;
}
char pop() {
if (top == -1)
return -1;
else
return stack[top--];
}
int priority(char x) {
if (x == '(')
return 0;
if (x == '+' || x == '-')
return 1;
if (x == '*' || x == '/')
return 2;
return 0;
}
void trimString(char string[], char newString[]) {
int i = 0, j = 0;
while (string[i] != '\0' && string[i] != 10) {
// Range of significant characters
if (string[i] >= '(' && string[i] <= '9') {
newString[j] = string[i];
i++, j++;
}
else {
i++;
}
}
newString[j] = 0;
}
void inputToRPN(char trimmedExp[], char rpnExp[]) {
char* e, x;
e = trimmedExp;
while (*e != '\0') {
// Add to RPN if character is alphanumeric
if (isalnum(*e)) {
rpnExp[index] = *e;
index++;
}
// Add to stack if is an open brace
else if (*e == '(')
push(*e);
// Add all operators to the expression until finding open braces
else if (*e == ')') {
while ((x = pop()) != '(') {
rpnExp[index] = x;
index++;
}
}
// If none of the above, that is an operator - check it's priority.
// If it's priority is less that that of the one on top of the stack add the operator from the top of the stack to the expression; untill it's priority is higher.
// At the end add current operator to the stack.
else {
while (priority(stack[top]) >= priority(*e)) {
rpnExp[index] = pop();
index++;
}
push(*e);
}
e++;
}
while (top != -1) {
rpnExp[index] = pop();
index++;
}
// Terminating character at the end of the string
rpnExp[index] = 0;
}
void pushRes(char x) {
printf("pushing: %c \n", x);
resStack[++resTop] = x;
}
char popRes() {
printf("poping \n");
if (resTop == -1)
return -1;
else
return resStack[resTop--];
}
int isValidOperator(char c) {
if (c == '/' || c == '*' || c == '+' || c == '-')
return 1;
else
return 0;
}
int calculateRPN(char rpnExp[]) {
// Doesnt do anything yet, just prints out the compiled reverse polish notation
char* c;
int result = 0;
c = rpnExp;
printf("Postfix expression: %s", rpnExp);
return result;
}
The problem I've stumbled upon is when the infix input has multiple digits say 10+2 the code will treat each digit individually. Therefore the whole expression will be invalid when calculating result. I'm almost certain the issue lies in this line of code:
// Add to RPN if character is alphanumeric
if (isalnum(*e)) {
rpnExp[index] = *e;
index++;
}
Despite that I've got no idea how should i treat multiple digits while adding them to the expression, since the input is in form of character and there can be N amount of digits that have coresponding ascii values which range from 0-9. Looking forward to your answears.
Edit: made it so the code compiles and the input is hard coded.
Okay, so thanks to Bodos suggestions I've fixed the issue. Adding one while loop in this section:
if (isalnum(*e)) {
rpnExp[index] = *e;
index++;
}
enabled me to add one character after every number (including the N digit ones).
Thanks to which I was later able to perform calculations in calculateRPN function that would eventually lead to correct answear.
The issue has been resolved.

Operators not inserting in the stack in C while trying to convert an infix expression to a postfix one

I am trying to implement an infix-to-postfix conversion program. On executing the code I get to see only alpha-numeric characters. Arithmetic operators are not printing. Upon debugging, I found the operators are not inserting in the stack. I couldn't find out the reason behind this.
Any help is appreciated.
#include<stdio.h>
#include <ctype.h>
#define MAX 50
char st[MAX];
int top = -1;
void push(char);
char pop();
int priority(char);
int main()
{
int i=0;
char x,s[50];
printf("Enter infix expression: ");
gets(s);
while(s[i]!='\0')
{
if(isalnum(s[i]))
printf("%c",s[i]);
else if(s[i] == '(')
push(s[i]);
else if(s[i] == ')')
{
while((x=pop())!='(')
printf("%c",x);
}
else
{
while(priority(st[top])>=priority(s[i]))
printf("%c",pop());
push(st[i]);
}
i++;
}
while(top!=-1)
printf("%c",pop());
}
void push(char x)
{
st[++top] = x;
}
char pop()
{
if(top == -1)
return -1;
else
return (st[top--]);
}
int priority(char x)
{
if(x == '(')
return 0;
if(x == '+' || x == '-')
return 1;
if(x == '*' || x == '/' || x == '%')
return 2;
}
As you correctly detected on your debugging session, you don't see operators in your postfix expression because you never push() them to your stack.
In fact
in the first if you check for alphanumeric characters
in the following else if you check for opening parenthesis
in the second else if you check for closing parenthesis
in the final else you manage pops from stack... but you didn't push anything! (1)
What you need to fix is the last else, where you have at least two distinct problems:
You access st[top] without checking top value. You need to manage the case in which top = -1, that would lead to out of bounds access of the stack array and to undefined behavior. I think that in that scenario you just need to push the operator
You push in the stack st[i]. Probably you meant s[i]
In this way the while analysing the expression becomes
while(s[i]!='\0')
{
if(isalnum(s[i]))
printf("%c ",s[i]);
else if(s[i] == '(' )
push(s[i]);
else if(s[i] == ')')
{
while((x=pop())!='(')
printf("%c ",x);
}
else
{
if( top != -1 )
{
while(priority(st[top])>=priority(s[i]))
printf("%c ",pop());
}
push(s[i]);
}
i++;
}
Input:
4*6+3
Output:
4 6 * 3 +
(I added a further space after each %c in printfs in order to improve output readability).
Note: You still have to fix some problems in operators priority management.

what does character '!' mean in array assignment in C

I have this code excerpt and don't understand some syntax in it.
What does string[index] = '!' mean?
What does string[index] == '~' mean?
And (string[index]++) probably means (the value of string[index] + 1)? The problem is that, in a larger context, that value should be a character. So, will it be treated as an ASCII code?
// Function to increment character and carry over if necessary
void incrementChar(char string[], int index)
{
if (string[index] == '\0')
{
string[index] = '!';
}
else if (string[index] == '~')
{
string[index] = '!';
incrementChar(string, index + 1);
}
else
{
string[index]++;
}
}

Extracting chars from inside '(' and ')' from char array in C

I am stuck on this problem:
A user writes a math expression and the program need to extract from it all subexpressions that are inside ( ) ex. (x+2) or (x+(y-2)).
For example, if the user enters 2-(5+(x-6)-(y+9)), the program should return (x-6), (y+9), (5+(x-6)-(y+9))
This is what I've tried to do.
#include<stdio.h>
int main()
{
char a[100];
int i=0,t,j=0;
printf("enter math expression:\n");
while( (a[i++]=getchar()) != '\n' && i < 100);
a[i] = '\0';
for (i=0; a[i]!='\0'; i++)
{
if (a[i]=='(')
{ printf("found (\n");
j++;
while (a[i] !=')')
printf("%c",a[i++]);
printf("%c",a[i]);
Since you are dealing with nested expressions, you need to keep a stack around in order to match parentheses. Ideally inside the loop you should:
Whenever found a '(', push position within the string into the stack
When a ')' is found, then pop from the stack the position of the matching '('. You have start-end indexes for your expression.
Continue until string is finished
Example (x + (y+2)):
i == 0 -> '(' -> s.push(0);
i == 1 -> 'x'
i == 2 -> '+'
i == 3 -> '(' -> s.push(3);
i == 4 -> 'y'
i == 5 -> '+'
i == 6 -> '2'
i == 7 -> ')' -> s.pop() [3, 7] contains '(y + 2)'
i == 8 -> ')' -> s.pop() [0, 8] contains '(x + (y+2))'
Let, s be a cstring in this context.
Since in valid mathematical expression parenthesis are balanced, we can observe that,
s+1 is balanced if s[0] is not '('
if s[0] is '(' then we are at the start of a parenthesis'ed expression.
At the case of #1 we do not care about the first character. So, we can set s = s+1 and start over again.
At the case of #2 we have to find the matched end for the first character. So, we divide it in two part. The matched expression and the tail. Both are valid expression. So, we start with them over again.
int main()
{
char s[] = "2-(5+(x-6)-(y+9))";// s have to be modifiable.
extractAndPrint(s, 0); // we are at start and 0 indicates balanced
return 0;
}
Now,
void extractAndPrint(char *s, int found)
{
if(s[0] == 0) return;//no more honey
if(!found){ //so far balanced
if(s[0] == '(') extractAndPrint(s+1, 1);// case 2
else extractAndPrint(s+1, 0); //this is the case 1
} else {//start of a expression
char *t;
//separates the end of current expression
//and the remaining part.
mark_end(s, 0, &t);
printf("(%s)\n", s);
extractAndPrint(s, 0);//potentially contain more expression
extractAndPrint(t, 0);//check past the previous exp
}
}
I liked recursion here too. It takes less thinking for me. Can be implemented in more elegant way.
void mark_end(char *s, int c, char **t)
{
if(c == 0){
if(s[0] == ')'){
*t = s+1;
*s = '\0';
} else if(s[0] == '('){
mark_end(s+1, c+1, t);
} else {
mark_end(s+1, c, t);
}
} else {
if(s[0] == ')'){
mark_end(s+1, c-1, t);
} else if(s[0] == '('){
mark_end(s+1, c+1, t);
} else {
mark_end(s+1, c, t);
}
}
}
OUTPUT:
(5+(x-6)-(y+9))
(x-6)
(y+9)
I recommend you to use state machine, in your case this state machine should be suitable :
so your main will be a kind of a switch case, take care of writing your pop and push fuctions and represent your heap with a good structure
You should use recursion to parse the string as a tree of parenthesis. Here is an example showing how to do it :
#include <stdio.h>
#include <string.h>
#define MAX_DATA 100
int mathexp(const char *exp, int start, int end)
{
int i = start;
while(i < (start + end) && exp[i] != ')') {
if(exp[i] == '(') {
i = mathexp(exp, i + 1, end) + 1;
} else {
i++;
}
}
char subexp[i - start];
memcpy(subexp, &exp[start], i - start);
subexp[i - start] = '\0';
printf("%s\n", subexp);
return i;
}
int main(int argc, char *argv[])
{
char input[MAX_DATA];
printf("Enter a math expression: ");
fgets(input, sizeof(input), stdin);
input[strcspn(input, "\r\n")] = '\0'; // remove trailing \r\n
mathexp(input, 0, strlen(input));
return 0;
}
and when you test it, you have :
Enter a math expression: 2-(5+(x-6)-(y+9))
x-6
y+9
5+(x-6)-(y+9)
2-(5+(x-6)-(y+9))

removing redundant braces from Spoj

I new at solving problems using C , I am trying to solve a SPOJ problem on
complicated Expression
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void removeBrackets(char *string , int position1 , int position2);
int main()
{
char exp[]="(a+b)-(c-d)-(e/f)";
char ops[]={'/','*','+','-','(',')','\0'};
char found[50][5];
int stack[3];
int i,j , k =0;
int l = (int)strlen(exp);
int lExp = l ;
char *p = exp ;
// //remove external brackets
// while (*(p+0)=='(' && *(p+strlen(p)-1)==')')
// removeBrackets(exp, 0, ((int)strlen(p)-1));
printf("expression : %s\n",exp);
printf("operators : %s\n",ops);
//find the operators and their location
l = 0 ;
for(i=0;i<lExp;i++)
{
for(j=0;j<strlen(ops);j++)
{
if(exp[i]==ops[j])
{
found[l][2]='N';
found[l][0]=i;
found[l][1]=ops[j];
if (exp[i-2]=='(' && exp[i+2]==')')
{
found[l][2]='Y';
found[l][3]=exp[i-3];
found[l][4]=exp[i+3];
}
if (found[l][1]=='(')
{
stack[k] = found[l][0];
k++;
}
else if(found[l][1]==')')
{
stack[k] = found[l][0];
if (stack[0] == 0 && stack[1] == lExp-1)
{
removeBrackets(exp, 0, (int)strlen(exp)-1);
break ;
}
removeBrackets(exp, stack[k-1], stack[k]);
//stack[k] = -1 ;
//stack[k-1] = -1 ;
k--;
}
printf("found '%c' at '%d' and within brackets: %c\n",found[l][1],found[l][0],found[l][2]);
l++;
}
}
}
//find where brackets are the corresponding sign in the brackets
for (i=0; i<l-1; i++)
{
if(found[i][2]=='Y')
{
//find higher precedence operators present nearby , and if their precedence is lower , then remove the brackets ,else keep the brackets
//1-find the operator inside the brackets
switch (found[i][1])
{
case '/':
printf("\nfound '/' within brackets");
removeBrackets(exp, found[i][0]-2, found[i][0]+2);
//remove the brackets
break;
case '*':
printf("\nfound '*' within brackets");
if (found[i][3] == '/' || found[i][4] == '/')
break ;
else
removeBrackets(exp, found[i][0]-2, found[i][0]+2);
break;
case '+':
printf("\nfound '+' within brackets");
if (found[i][3] == '/' || found[i][4] == '/' || found[i][3] == '*' || found[i][4] == '*' )
break ;
else
removeBrackets(exp, found[i][0]-2, found[i][0]+2);
break;
case '-':
printf("\nfound '-' within brackets");
if (found[i][3] == '/' || found[i][4] == '/' || found[i][3] == '*' || found[i][4] == '*' || found[i][4] == '+' || found[i][3] == '+')
break ;
else
removeBrackets(exp, found[i][0]-2, found[i][0]+2);
break;
default:
break;
}
}
}
printf("\nstring modified : %s",exp);
}
void removeBrackets(char *string, int position1 , int position2)
{
char *p = string;
char *newString = (char *)malloc(strlen(string -1));
int i = 0 , j =0 ;
for (i = 0 ; i <strlen(string); i++)
{
if (i == position1 || i == position2)
continue ;
else
{
newString[j] = *(p+i);
j++ ;
}
}
newString[j]='\0';
strcpy(string, newString);
printf("\n-----after removing brackets :- %s\n",newString);
free(newString);
}
What i am doing is , scanning all the words , then storing the found operators and brackets in an array 'Found' , stack is an array to check the sequence of '(' and ')' and 'ops' is an array to store all possible operators and brackets ,
then , if an operator is found within the brackets , then depending on the precendence of operators at left and right , brackets are removed .
But , after trying a lot , i am not able to come up with solution to remove brackets , for all test cases .
I searched on internet , they have used tree to solve this problem .
Can anybody please suggest some changes in my code to solve out the problem ..??
or is it that , the problem cannot be solved without trees ??

Resources