Char array in multiple test cases - c

#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>
#define SIZE 100
char stack[SIZE];
int top = -1;
void push(char item)
{
if(top >= SIZE-1)
{
printf("\nStack Overflow.");
}
else
{
top = top+1;
stack[top] = item;
}
}
char pop()
{
char item;
if(top <0)
{
printf("stack under flow: invalid infix expression");
}
else
{
item = stack[top];
top = top-1;
return(item);
}
}
int is_operator(char symbol)
{
if(symbol == '^' || symbol == '*' || symbol == '/' || symbol == '+' || symbol =='-')
{
return 1;
}
else
{
return 0;
}
}
int precedence(char symbol)
{
if(symbol == '^')
{
return(5);
}
else if(symbol == '/')
{
return(4);
}
else if(symbol == '*')
{
return(3);
}
else if(symbol == '+' )
{
return(2);
}
else if(symbol == '-' )
{
return(1);
}
else
{
return(0);
}
}
void InfixToPostfix(char infix_exp[], char postfix_exp[])
{
int i, j;
char item;
char x;
push('(');
strcat(infix_exp,")");
i=0;
j=0;
item=infix_exp[i];
while(item != '\0')
{
if(item == '(')
{
push(item);
}
else if( isdigit(item) || isalpha(item))
{
postfix_exp[j] = item; /* add operand symbol to postfix expr */
j++;
}
else if(is_operator(item) == 1) /* means symbol is operator */
{
x=pop();
while(is_operator(x) == 1 && precedence(x)>= precedence(item))
{
postfix_exp[j] = x; /* so pop all higher precendence operator and */
j++;
x = pop(); /* add them to postfix expresion */
}
push(x);
push(item);
}
else if(item == ')')
{
x = pop();
while(x != '(')
{
postfix_exp[j] = x;
j++;
x = pop();
}
}
else
{
printf("\nInvalid infix Expression.\n");
}
i++;
item = infix_exp[i];
}
if(top>0)
{
printf("\nInvalid infix Expression.\n");
}
if(top>0)
{
printf("\nInvalid infix Expression.\n");
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
char infix[SIZE], postfix[SIZE]; /* declare infix string and postfix string */
scanf("\n%[^\n]s",infix);
InfixToPostfix(infix,postfix); /* call to convert */
//printf("Postfix Expression: ");
printf("%s\n",postfix);
/* print postfix expression */
}
return 0;
}
This is the code to convert infix to postfix expression I am using multiple test cases the problem is the second time(second test case the postfix_exp is printing more than it should)
Input
2
a+b*(c^d-e)^(f+gh)-i
a(b+c)/d
Output
abcd^e-fgh*+^*+i-
abc+d/fgh+^*+i-
Can you tell me what is wrong because of which "fgh+^*+i-" the extra expression from the previous expression is being concatenated at the end of the output?
The postfix_exp seems to be overwritten but I was expecting a new assigned postfix expression. Why is it that earlier data(data from previous test case) is saved?
Please ask any further query in the comments section

You did not closed postfix_exp with the terminating '\0'. After the first iteration postfix will look like something like this
XXXXXXXXXXX0
After the shorter 2nd input it will look something like
YYYYYYYXXXX0
Where X represent the characters written in the first iteration and Y the ones which in the second. So when you print it it will contain the last iteration results too.
Add this postfix_exp[j] = '\0'; before the if (top>0) line.
Note that this is still undefined behavior since postfix array is unitialized and there is no guarantee that it will be zeroed out.

you should clos postfix_exp with the terminating '\0' by adding
Add this postfix_exp[j] = '\0';
before the if (top>0) line.

Related

Check if the input string consisting of braces is well-formed

I have spent the last two hours trying to debug my code that is supposed to check if the input consists of well-formed brackets. What I mean by well formed is that ()()[] or ([()]) are acceptable but ((((() is not.
I'm not allowed to use any header file apart from <stdio.h>
#include <stdio.h>
void cross(char str[], int i, int j) {
str[i] = 'X';
str[j] = 'X';
}
int iscrossed(char str[]) {
int i = 0;
while (str[i] != '\0') {
if (str[i] != 'X')
return 0;
i++;
}
return 1;
}
int check(char str[]) {
int i = 1, j;
while (str[i] != '\0') {
if (str[i] == ')') {
for (j = i - 1; j >= 0; j--) {
if (str[j] == '(') {
cross(str, str[i], str[j]);
}
break;
}
} else
if (str[i] == ']') {
for (j = i - 1; j >= 0; j--) {
if (str[j] == '[') {
cross(str, str[i], str[j]);
}
break;
}
}
i++;
}
if (iscrossed(str) == 1)
return 1;
else
return 0;
}
int main() {
char str[20];
scanf("%s", str);
printf("%d\n", check(str));
}
For certain inputs the program prints a zero followed by a segmentation fault and for the others it just prints a zero.
Please keep in mind that I'm a beginner programmer so please don't include too much heavy stuff in your hints. I'd be grateful for any help on this.
Edit: It would be wonderful if your answer tells me the errors in my code, because that was my question in the first place.
Here a simple recursive solution:
#include <stdio.h>
int brace(const char **s, char cc)
{
while(1) {
if(**s == cc) { return 0; }
switch(**s) {
case '\0': return -1;
case '[': ++(*s); if(brace(s, ']')) { return -1; } ++(*s); break;
case '{': ++(*s); if(brace(s, '}')) { return -1; } ++(*s); break;
case '(': ++(*s); if(brace(s, ')')) { return -1; } ++(*s); break;
case ']':
case '}':
case ')': return -1;
default: ++(*s);
}
}
}
int check_brace(const char *s)
{
return brace(&s, '\0');
}
int main()
{
printf("%d\n", check_brace(" hekl(l o{ asdf } te)ts()({})"));
}
Returns -1 when somethings wrong. Otherwise 0.
There are multiple problems in your code:
you call cross(str, str[i], str[j]); instead of cross(str, i, j); when you find matches for parentheses and brackets.
the break statement should be moved inside the if block.
your method does not allow detection of nesting errors
your method would have undefined behavior if str is an empty string (which you cannot input via scanf())
Here is a modified version:
#include <stdio.h>
void cross(char str[], int i, int j) {
str[i] = str[j] = 'X';
}
int iscrossed(char str[]) {
int i = 0;
while (str[i] != '\0') {
if (str[i] != 'X')
return 0;
i++;
}
return 1;
}
int check(char str[]) {
int i = 0, j;
while (str[i] != '\0') {
if (str[i] == ')') {
for (j = i - 1; j >= 0; j--) {
if (str[j] == '(') {
cross(str, i, j);
break;
}
}
} else
if (str[i] == ']') {
for (j = i - 1; j >= 0; j--) {
if (str[j] == '[') {
cross(str, i, j);
break;
}
}
}
i++;
}
return iscrossed(str);
}
int main() {
char str[80];
if (scanf("%79s", str) == 1) {
printf("%d\n", check(str));
}
return 0;
}
Here is a simpler alternative:
#include <stdio.h>
const char *check(const char str[], int endc) {
while (str) {
int c = *str++;
switch (c) {
case '(': str = check(str, ')'); break;
case '[': str = check(str, ']'); break;
case '{': str = check(str, '}'); break;
case ')':
case ']':
case '}':
case '\0': return c == endc ? str : NULL;
}
}
return NULL;
}
int main() {
char str[80];
if (fgets(str, sizeof str, stdin)) {
printf("%d\n", check(str, '\0') != NULL);
}
return 0;
}
Pseudocode of a possible answer:
initialize char[] unclosed
int latest_unclosed_index = -1
for each char in string {
if char == opening_bracket {
latest_unclosed_index += 1
unclosed[latest_unclosed_index] = char
} else if char == closing_bracket {
if latest_unclosed_index < 0 {
return false
} else if char == closing_of(unclosed[latest_unclosed_index]) {
unclosed[latest_unclosed_index] = null
latest_unclosed_index -= 1
} else {
return false
}
}
}
if latest_unclosed_index == -1 {
return true
} else {
return false
}
This works by keeping an array of all unclosed opening brackets in the order that you encounter them in, and removing them whenever you encounter a closing bracket, as a sort of stack.
This solution has a complexity of O(n).
A problem with this implementation is that there is an unknown amount of brackets in string, which may cause the array to overflow if it isn't large enough.
Solution:
To be sure that this solution doesn't overflow, the size of the array should be at least half the size of the input string, and you'll have to check at each character if there are enough characters left in the input string to be able to completely close all brackets.
Use a list implementation (or write your own) instead of an array for unclosed.
If its ok for you to use stdlib.h then,
#include <stdio.h>
#include <stdlib.h>
#define bool int
// structure of a stack node
struct sNode {
char data;
struct sNode* next;
};
// Function to push an item to stack
void push(struct sNode** top_ref, int new_data);
// Function to pop an item from stack
int pop(struct sNode** top_ref);
// Returns 1 if character1 and character2 are matching left
// and right Brackets
bool isMatchingPair(char character1, char character2)
{
if (character1 == '(' && character2 == ')')
return 1;
else if (character1 == '{' && character2 == '}')
return 1;
else if (character1 == '[' && character2 == ']')
return 1;
else
return 0;
}
// Return 1 if expression has balanced Brackets
bool areBracketsBalanced(char exp[])
{
int i = 0;
// Declare an empty character stack
struct sNode* stack = NULL;
// Traverse the given expression to check matching
// brackets
while (exp[i])
{
// If the exp[i] is a starting bracket then push
// it
if (exp[i] == '{' || exp[i] == '(' || exp[i] == '[')
push(&stack, exp[i]);
// If exp[i] is an ending bracket then pop from
// stack and check if the popped bracket is a
// matching pair*/
if (exp[i] == '}' || exp[i] == ')'
|| exp[i] == ']') {
// If we see an ending bracket without a pair
// then return false
if (stack == NULL)
return 0;
// Pop the top element from stack, if it is not
// a pair bracket of character then there is a
// mismatch.
// his happens for expressions like {(})
else if (!isMatchingPair(pop(&stack), exp[i]))
return 0;
}
i++;
}
// If there is something left in expression then there
// is a starting bracket without a closing
// bracket
if (stack == NULL)
return 1; // balanced
else
return 0; // not balanced
}
// Driver code
int main()
{
char exp[100] = "{()}[]";
// Function call
if (areBracketsBalanced(exp))
printf("Balanced \n");
else
printf("Not Balanced \n");
return 0;
}
// Function to push an item to stack
void push(struct sNode** top_ref, int new_data)
{
// allocate node
struct sNode* new_node
= (struct sNode*)malloc(sizeof(struct sNode));
if (new_node == NULL) {
printf("Stack overflow n");
getchar();
exit(0);
}
// put in the data
new_node->data = new_data;
// link the old list off the new node
new_node->next = (*top_ref);
// move the head to point to the new node
(*top_ref) = new_node;
}
// Function to pop an item from stack
int pop(struct sNode** top_ref)
{
char res;
struct sNode* top;
// If stack is empty then error
if (*top_ref == NULL) {
printf("Stack overflow n");
getchar();
exit(0);
}
else {
top = *top_ref;
res = top->data;
*top_ref = top->next;
free(top);
return res;
}
}
Features
Support nested parantheses like (())
Support bad nestings such as ([)]
Commented but not by me (see the below spoiler)
Note: i feel guilty that i have copied code from here
The algorithm
Pseudocode Like Block code!
If it's not ok for you to use stdlib.h,then someone may edit this code and remove the errors that occur when we remove that line(#include <stdlib.h>),I am not a c guy and i don't know to edit,i just copy pasted !
First attempt didn't worked with bad nesting, as MOehm wrote in the comments.
Storing the opened braces that not have been closed yet helps to recognize bad nesting. The last opened brace will determine which closing brace is need.
#include <stdio.h>
int check(char str[], int size)
{
char opened[size/2];
char close;
int i = 0;
int pos = 0;
int error = 0;
while((i < size) || (pos < size/2))
{
if((str[i] == '(') || (str[i] == '['))
{
opened[pos] = str[i];
pos++;
}
else if((str[i] == ')') || (str[i] == ']'))
{
if(str[i] == close)
{
opened[pos-1] = 0;
pos--;
}
else
{
error = 1;
break;
}
}
printf("%s\n", opened);
if(pos > 0)
{
switch(opened[pos-1])
{
case '(':
close = ')';
break;
case '[':
close = ']';
break;
}
}
else
close = 0;
i++;
}
return error;
}
int main() {
char str[20];
printf("%d\n", check(str, sizeof(str)));
return 0;
}

Converting infix to postfix not showing proper symbols

I was trying to write a code to convert infix expression into postfix expression , I have the source code here and when I compile and give the input say 'a+b' it returns 'ab?' as the answer it does not show the operator symbols at all. Can you guys please tell me where I have gone wrong.!!
It also shows this warning when I compile
infpos.c:74:1: warning: non-void function does not return a value in all control paths [-Wreturn-type]
PS: I got to know what is the error.. Thank you
(The error was in the line 58 I had to use prefix increment but I had used postfix increment)
#include<stdio.h>
#include<ctype.h>
#define max 30
void main()
{
char inf[30],post[30];
void convert(char [],char []);
printf("Enter the infix exxpression\n");
scanf("%s",inf);
convert(inf,post);
printf("Postfix expression is\n");
printf("%s\n",post);
}
void convert(char inf[],char post[])
{
int i,j=0,top=-1,f=1,test;
char stack[30],ch,x;
int check(char);
int pre(char);
for(i=0;inf[i]!='\0';i++)
{
ch = inf[i];
test = check(ch);
switch(test)
{
case 1:
post[j++] = ch;
break;
case 2:
stack[++top] = ch;
break;
case 3:
while((x=stack[top--])!='(')
post[j++] = x;
break;
case 4:
do
{
if(top==-1)
f = 1;
else if(stack[top] == '(')
f = 1;
else if(pre(ch)>pre(stack[top]))
f = 1;
else
{
post[j++] = stack[top--];
f = 0;
}
}while(f==0);
stack[top++] = ch;
break;
}
}
while(top!=-1)
post[j++] = stack[top--];
post[j] = '\0';
}
int pre(char op)
{
if(op == '+' || op=='-')
return 1;
else if(op == '/' || op=='*' || op =='%')
return 2;
else if(op=='^')
return 3;
}
int check(char ch)
{
if(isalnum(ch))
return 1;
else if(ch=='(')
return 2;
else if(ch == ')')
return 3;
else if(ch == '+' || ch =='-' || ch=='/' || ch =='*' || ch=='%' || ch=='^')
return 4;
else
return 5;
}

reversing operator precedence in infix expression

Write a program which accepts a valid infix expression and provide its corresponding postfix expression. Consider following assumptions:
• There are 5 operators (+,-,*,/ and ^).
• + and – follow right to left associativity
• * and / also follow right to left associativity
• ^ follow left to right associativity
#include<stdio.h>
#include<ctype.h>
char stack[20];
int top = -1;
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;
else if(x == '*' || x == '/')
return 2;
}
void main()
{
char exp[20];
char *e, x;
printf("Enter the expression :: ");
scanf("%s",exp);
e = exp;
while(*e != '\0')
{
if(isalnum(*e))
printf("%c",*e);
else if(*e=='^')
{
while(priority(stack[top]) >=priority(*e))
printf("%c",pop());
push(*e);
}
else
{
while(priority(stack[top]) > priority(*e))
printf("%c",pop());
push(*e);
}
e++;
}
while(top != -1)
{
printf("%c",pop());
}
}
This program gives an infinite loop upon execution.
I get following output after entering any expression,
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
When there is no element in the stack i.e. top = -1 in your code and you call priority on that it return garbage + IMO top should be returning the no. of elements in the stack for ease rather than position in array.
Apart from this the changed associativity will not serve the purpose as a-b is not equal to b-a usually.
Here is the corrected code:
#include<stdio.h>
#include<ctype.h>
char stack[20];
int top = 0; //CHANGE 1 -NOW IT MEANS NO. OF ELEMENTS IN THAT STACK
void push(char x)
{
stack[top++] = x;
}
void swap(char c[],int i, int j)
{
char temp;
temp =c[i];
c[i] = c[j];
c[j] = temp;
}
char pop()
{
return stack[--top]; //CHANGE 2
}
int priority(char x)
{
if(x=='^')
return 3; //CHANGE 3 - CONCEPTUAL
if(x == '+' || x == '-')
return 1;
else if(x == '*' || x == '/')
return 2;
return -1;
}
int main()
{
char exp[20];
char *e, x;
printf("Enter the expression :: ");
scanf("%s",exp);
//CHANGE INDUCED AS ASSOCIATIVITY HAS BEEN REVERSED FOR OPERATORS OTHER THAN '^'
int i=0,length=strlen(exp);
while(i<length/2) //REVERSING THE INPUT EXPRESSION
{
swap(exp,i,length-i-1);
++i;
}
e = exp;
while(*e != '\0')
{
if(*(e+1)=='^') //ASSOCIATIVITY OF THIS OPERATOR HAS BEEN KEPT AS USUAL HENCE REVERSING A SMALL PART JUST TO COMPUTE IT AS USUAL
{
swap(e,0,2);
}
x=*e; //CHANGE 4
if(isalnum(x))
printf("%c",x);
else
{
while((top>0)&&(priority(stack[top-1]) > priority(x))) //CHANGE 5
printf("%c",pop());
push(x);
}
e++;
}
while(top>0) //CHANGE 5
{
printf("%c",pop());
}
return 0;
}
INPUT:
a+b^c
cab^-
a+b*c^d
OUTPUT (with reversed associativity of operators except '^'):
1.
bc^a+
ab^c+
cd^b*a+

What does it mean by " item=infix_exp[i++]; " in the following C code?

What does it mean by item=infix_exp[i++]; in the following C code? Line no 21. It is for infix to postfix conversion. As far as I know, here i is array index. But why is it incrementing without any loop?
This is the Code
#include<stdio.h>
#include<conio.h>
#define SIZE 100
int top = -1;
char stack[SIZE];
void push(char item);
char pop();
int is_operator(char symbol);
int precedence(char symbol);
void main()
{
int i;
int j;
char infix_exp[SIZE], postfix_exp[SIZE];
char item;
char x;
printf("\nEnter Infix expression in parentheses: \n");
gets(infix_exp);
i=0;
j=0;
item=infix_exp[i++]; /* HERE */
while(item != '\0')
{
if(item == '(')
{
push(item);
}
else if((item >= 'A' && item <= 'Z') ||
(item >= 'a' && item <= 'z'))
{
postfix_exp[j++] = item;
}
else if(is_operator(item) == 1)
{
x=pop();
while(is_operator(x) == 1 && precedence(x)
>= precedence(item))
{
postfix_exp[j++] = x;
x = pop();
}
push(x);
push(item);
}
else if(item == ')')
{
x = pop();
while(x != '(')
{
postfix_exp[j++] = x;
x = pop();
}
}
else
{
printf("\nInvalid Arithmetic Expression.\n");
getch();
}
item = infix_exp[i++];
}
postfix_exp[j++] = '\0';
printf("\nArithmetic expression in Postfix notation: ");
puts(postfix_exp);
getch();
}
void push(char item)
{
if(top >= SIZE-1)
{
printf("\nStack Overflow. Push not possible.\n");
}
else
{
top = top+1;
stack[top] = item;
}
}
char pop()
{
char item = NULL;
if(top <= -1)
{
printf("\nStack Underflow. Pop not possible.\n");
}
else
{
item = stack[top];
stack[top] = NULL;
top = top-1;
}
return(item);
}
int is_operator(char symbol)
{
if(symbol == '^' || symbol == '*' || symbol == '/' ||
symbol == '+' || symbol == '-')
{
return 1;
}
else
{
return 0;
}
}
int precedence(char symbol)
{
if(symbol == '^')
{
return(3);
}
else if(symbol == '*' || symbol == '/')
{
return(2);
}
else if(symbol == '+' || symbol == '-')
{
return(1);
}
else
{
return(0);
}
}
item=infix_exp[i++]; means to fetch ith element of the array to item, then increment i by 1.
It seems the line is there because the author of the code prefered to write item=infix_exp[i++]; twice (the another one is in line 59) to using while((item=infix_exp[i++]) != '\0').
item=infix_exp[i++]; is equivalent to
item=infix_exp[i];
i++;
except that latter has one more sequence point.
It is just the same as
item=infix_exp[i];
i = i + 1;
The statement where you are getting confused is
item=infix_exp[i++]
Before this line of statement if the value of i is 0 then in this line the value of i is also 0 but the value of i in the next line is 1.
This statement is not in loop but the value of i is used in a loop. Each time the loop iterates the value of i is increased by one. Besides, i++ has no relation with loop. If you want to make the effect of increment in the very next line then you can do so.

Spacing between the operands of an Infix-to-Postfix program in C

I've searched the site to see if there are any similar questions to mine, but I can't seem to find one which offers a working solution. Below is the code to a fully functional infix to postfix converter for arithmetic syntax.
The issue is that if the user enters a string such as 23+89, the infix output is 2389+. This is of course correct, however I wish to add separators between the operands to distinguish between 23 and 89. How can this be implemented with the array I am using? Do I need to add a whitespace character between the operands in the array? How can this be achieved?
Any insight will be greatly appreciated.
#include <stdio.h>
#include <stdbool.h>
#include <ctype.h>
#include <string.h>
#define MAX 100 // maximum number of input characters
int precedence(char x);
struct stack
{
char my_stack[MAX];
int pointer;
};
int precedence(char x)
{
if(x == '(')
return(0);
if(x == '+' || x == '-')
return(1);
if(x == '*' || x == '/')
return(2);
return(3);
}
int main(void)
{
struct stack S;
S.pointer = 0;
char c;
char output[MAX]; // stores output
int out_count = 0; // stores no. of characters of output
char data; // stores data being popped off the stack
printf("Enter an expression to check:\n");
fflush(stdout);
while(('\n' != (c=getchar())))
{
if(isdigit(c)) // if an operand is found print to screen
{
output[out_count] = c;
out_count++;
}
else if(c == '(') // if ( is found push on stack
{
S.pointer = S.pointer +1;
S.my_stack[S.pointer] = c;
}
else if(c == ')') // if ) is found pop stack until ( is found
{
while(!(S.my_stack[S.pointer] == '('))
{
data = S.my_stack[S.pointer];
output[out_count] = data;
out_count++;
S.pointer = S.pointer -1;
}
S.pointer = S.pointer -1; // pop the extra (
}
else if(c == '*' || c == '/' || c == '+' || c == '-')
{
if((S.pointer) == 0)
{
S.pointer = S.pointer +1;
S.my_stack[S.pointer] = c;
}
else
{
if(precedence(S.my_stack[S.pointer]) > precedence(c))
{
// pop stack
int i;
for(i=(S.pointer); i >= 0; i--)
{
if(c == '(' || c == ')')
continue;
output[out_count] = c;
out_count++;
}
S.pointer = 0;
}
else
{
// push c on stack
S.pointer = S.pointer +1;
S.my_stack[S.pointer] = c;
}
}
}
}
int j = S.pointer;
while(j != 0)
{
if(S.my_stack[j] == '(')
continue;
output[out_count] = S.my_stack[j];
out_count++;
j--;
}
output[out_count+1] = '\0';
int k=0;
while(output[k] != '\0') // go through output array and print
{
printf("%c", output[k]);
k++;
}
return 0;
}
23+89, the infix output is 2389+. This is of course correct,
Well, no. 2389 is not the same as 23 and 89.
You could either add whitespace, or an explicit "push" operator. HP calculators often use an up arrow ↑ symbol to show that operation.

Resources