I was making a C program to convert infix expression to postfix expression in which unwanted symbols are showing instead of operators
The output is like abc##$^ for input (a+b+c).
I am hereby attaching the code
//to convert infix expression to postfix expression
#include <stdio.h>
#include <conio.h>
#include <string.h>
void push(char);
char pop();
int is_operator(char);
int precedence(char);
char stack[100];
int top=-1;
void main()
{
int i=0,j=0,count;
char infix[100],item,x;
char postfix[100];
clrscr();
printf("Enter Infix String");
gets(infix);
count= strlen(infix);
for(i=0;i!=count;i++){
item=infix[i];
if(item=='('){
push(item);
}
else if((item>='A'&& item<='Z')||(item>='a' && item<='z')){
postfix[j]=item;
j++;
}else if(is_operator(item)==1){
x=pop();
if(precedence(x)>precedence(item)){
postfix[j]=x;
j++;
}
else{
push(item);
}
}else if(item==')'){
char a;
a=pop();
while(a!='('){
postfix[j]=a;
a=pop();
}
}else{
printf("Invalid Expression");
}
}
postfix[j]='\0';
printf("Postfix Expression\n");
puts(postfix);
getch();
}
void push(char a)
{
char y;
y=a;
top++;
stack[top]=y;
}
char pop()
{
char ch;
ch=stack[top];
top--;
return(ch);
}
int is_operator(char i)
{
if(i=='+'||i=='-'||i=='/'||i=='*'||i=='%'){
return(1);
}else{
return(0);
}
}
int precedence(char c)
{
if(c=='/'||c=='*'||c=='%'){
return(2);
}else if(c=='+'||c=='-'){
return(1);
}else{
return(0);
}
}
Related
I am trying to make an Insert or Update menu option in my Main Menu, that can update the Quiz Scores (qz1,qz2,qz3) of any student on the array. However, I am getting stuck at displaying after inserting, and unable to figure out how to do the menu inside the menu.
Here is whare I am stuck at, adding the 'Insert' (or 'Update') Main Menu item:
char nm[31];
int qz1,qz2,qz3,sm;
int i,p;
if (isempty()){
printf("Array is empty.\n");
system("pause");
}
else{
p=search(n);
if (p==-1){
printf("Not found.\n");
system("pause");
}
else {
display();
}
}
}
I can only get to display, but cannot figure out how to display the related quiz scores of the same student, after inputting the student name.
Hope you can help out. Background is I'm doing self-studying for C Programming. Started with Global and Local functions calling, then working on Arrays, and most recently, using a Switch/Menu. Next challenge is to try and update the file by updating the quizzes only without changing the name.
Here is the full program code:
#include <stdlib.h>
#include <string.h>
#define MAX 3
char name[MAX][31];
int q1[MAX],q2[MAX],q3[MAX];
int last;
int initialize();
void add(char n[31], int a, int b, int c);
void ins(char n[31]);
void del(char n[31]);
void display();
int search(char n[31]);
int isfull();
int isempty();
int menu();
float average(int a, int b, int c);
void save();
void retrieve();
int main(){
char nm[31];
int qz1,qz2,qz3,m;
initialize();
retrieve();
while(1){
m=menu();
switch(m){
case 1 : system("cls");printf("Insert Mode\n");
printf("Input Name: ");scanf("%s",nm);
printf("Input Quiz1: ");scanf("%d",&qz1);
printf("Input Quiz2: ");scanf("%d",&qz2);
printf("Input Quiz3: ");scanf("%d",&qz3);
add(nm,qz1,qz2,qz3);break;
case 2 : system("cls");printf("Insert Mode\n");
printf("Input Name: ");scanf("%s",nm);ins(nm);break;
case 3 : system("cls");printf("Delete Mode\n");
printf("Input Name: ");scanf("%s",nm);del(nm);break;
case 4 : display();break;
case 5 : save();printf("File Saved.\n");system("pause");exit(0);
default: printf("Please select an option between 1-5 only\n");system("pause");
}
}
return 0;
}
int initialize(){
last = -1;
}
void add(char n[31], int a, int b, int c){
if (isfull()){
printf("Array is full!.\n");
system("pause");
}
else{
last = last+1;
strcpy(name[last],n);
q1[last]=a;
q2[last]=b;
q3[last]=c;
}
}
void ins(char n[31]){
char nm[31];
int qz1,qz2,qz3,sm;
int i,p;
if (isempty()){
printf("Array is empty.\n");
system("pause");
}
else{
p=search(n);
if (p==-1){
printf("Not found.\n");
system("pause");
}
else {
display();
}
}
}
void del(char n[31]){
int i,p;
if (isempty()){
printf("Array is empty.\n");
system("pause");
}
else{
p=search(n);
if (p==-1){
printf("Not found.\n");
system("pause");
}
else {
for (i=p;i<last;i++){
strcpy(name[i],name[i+1]);
q1[i]=q1[i+1];
q2[i]=q2[i+1];
q3[i]=q3[i+1];
}
last--;
}
}
}
int search(char n[31]){
int i;
for (i=0;i<=last;i++)
if (strcmp(name[i],n)==0)
return i;
return -1;
}
void display(){
int i;
float av;
system("cls");
printf("No.\tStudent\tQuiz1\tQuiz2\tQuiz3\tAverage\tRemarks\n");
for(i=0;i<=last;i++){
av = average(q1[i],q2[i],q3[i]);
printf("%d.)\t%s\t%d\t%d\t%d\t%6.2f\t%s\n",i+1,name[i],q1[i],q2[i],q3[i],av, av>=75.0 ? "Passed":"Failed");
}
system("pause");
}
int menu(){
int op;
system("cls");
printf("Menu\n");
printf("1.) Add Student record\n");
printf("2.) Insert Student record\n");
printf("3.) Delete Student record\n");
printf("4.) Display\n");
printf("5.) Exit\n");
printf("Select(1-5): ");
scanf("%d",&op);
return(op);
}
int isfull(){
return(last==MAX-1);
}
int isempty(){
if (last==-1)
return 1;
else
return 0;
}
float average(int a, int b, int c){
return((a+b+c)/3.0);
}
/*saving function*/
void save(){
FILE *fp;
int i;
fp = fopen("Update.dbf","w+");
if (fp==NULL){
printf("Error - File Not Found.\n");
system("pause");
}
else{
for (i=0;i<last;i++)
fprintf(fp,"%s\t%d\t%d\t%d\n",name[i],q1[i],q2[i],q3[i]);
}
fclose(fp);
}
void retrieve(){
FILE *fp;
int i;
char n[31];
int qz1,qz2,qz3;
fp = fopen("Update.dbf","r+");
if (fp==NULL){
printf("Error - File Not Found.\n");
system("pause");
}
else {
while(!feof(fp)){
fscanf(fp,"%s\t%d\t%d\t%d\n",n,&qz1,&qz2,&qz3);
add(n,qz1,qz2,qz3);
}
}
fclose(fp);
}
I was creating on a very basic program in C which takes a word from user as input and searches for how many times it appears in a text file and gives output.
The code is:
#include<stdio.h>
#include<string.h>
int main()
{
char user[20];
char word[20];
int i,pos=0,sum=0;
char c;
c='a';
printf("Enter the word you want to look for\n");
gets(user);
FILE *p;
p=fopen("D:\\trees.txt","r+");
do
{
pos=0;
fscanf(p,"%s",word);
if(c!=EOF)
{
if(strlen(word)==strlen(user))
{
for(i=0;i<strlen(user);i++)
{
if(word[i]==user[i]||word[i]==user[i]+32||word[i]==user[i]-32)
{
}
else
{
pos=1;
break;
}
}
}
else
{
pos=1;
}
if(pos=0)
{
sum++;
}
}
}
while(c!=EOF)
;printf("\nNumber of times %s appears is %d",user,sum);
fclose(p);
}
Now the program takes the input fine, but doesn't give any output.
Looks like this:
What have I done wrong?
Looking at the comments, your code should be something like:
#include<stdio.h>
#include<string.h>
#include <ctype.h>
int main()
{
char user[20];
char word[20];
int n, pos=0, sum=0;
unsigned int i, l;
FILE *p;
do {
printf("Enter the word you want to look for\n");
} while (gets(user)==0);
user[strlen(user)-1]= '\0'; // remove trailing \n
if ((p=fopen("D:\\trees.txt","r+"))==0) {printf("Error opening file\n"); exit(0);}
do
{
pos=0;
n= fscanf(p,"%s",word);
if (n==1)
{
if(strlen(word)==(l=strlen(user)))
{
for(i=0; i<l; i++)
{
if(!(word[i]==user[i]||word[i]==tolower(user[i])||word[i]==toupper(user[i])))
{
pos=1;
break;
}
}
}
else pos=1;
if(pos==0) sum++;
}
}
while(n==1);
printf("\nNumber of times %s appears is %d",user,sum);
fclose(p);
return(1);
}
(with some optimizations and additions)
I am trying to convert infix notation to postfix notation using stack. I have written the following code but it is giving me error:
/Users/apple/Desktop/infix.c|49|error: expected expression
and I am unable to find the error. Please help me to correct this code.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define MAX 100
char st[MAX];
int top = -1;
void push(char st[],char);
char pop(char st[]);
void InfixtoPostfix(char source[],char target[]);
int getPriority(char);
int main(){
char infix[100],postfix[100];
printf("enter any infix expression");
fflush(stdin);
gets(infix);
strcpy(postfix,"");
InfixtoPostfix(infix,postfix);
printf("\nthe corresponding postfix expression is:");
puts(postfix);
return 0;
}
void InfixtoPostfix(char source[],char target[]){
int i=0,j=0;
char temp;
strcpy(target,"");
while(source[i]!='\0')
{
if(source[i]=='(')
{
push(st,source[i]);
i++;
}
else if(source[i]==')')
{
while((top!=-1)&&(st[top]!='('))
{
target[j]=pop(st);
j++;
}
if(top==-1)
{
printf("\nincorrect syntax");
exit(1);
}
temp=pop(st);
i++;
else if((isdigit(source[i]))||(isalpha(source[i]))
{
target[j]=source[i];
j++;
i++;
}
else if(source[i]=='+'||source[i]=='- '||source[i]=='*'||source[i]='/'||source[i]=='%d')
{
while((top!=-1)&&(st[top]!='(')&&(getPriority(st[top])>getPriority(source[i])))
{
target[j]=target[i];
i++;
}
push(st,source[i]);
i++;
}
else{
printf("\nincorrect expression");
exit(1);
}
}
while((top!=-1)&&(st[top]!='('))
{
target[j]=pop(st);
j++;
}
target[j]='\0';
}
}
int getPriority(char op)
{
if(op=='/'||op=='*'||op=='%'||op=='%')
return 1;
else if(op=='+'||op=='-')
return 0;
}
void push(char st[],char val)
{
if(top==MAX-1)
printf("overflow");
else{
top++;
st[top]=val;
}
}
char pop(char st[])
{
char val=' ';
if(top==-1)
printf("underflow");
else{
val=st[top];
top--;
}
return val;
}
Many problems, the most important one being
else if((isdigit(source[i]))||(isalpha(source[i]))
lacks a closing parentheses, your coding style makes it difficult to notice
else if ((isdigit(source[i]) != 0) || (isalpha(source[i]) != 0))
And don't use gets() it's deprecated, in your case
fgets(infix, sizeof(infix), stdin);
would work, and will have the benefit of preventing a buffer overflow.
While there are so many issues in the code,
this one here is the most horror:
if(top==-1)
{
printf("\n incorrect syntex");
exit(1);
}
temp=pop(st);
i++;
else if((isdigit(source[i]))||(isalpha(source[i]))
{
target[j]=source[i];
j++;
i++;
}
No, you are not doing that right. FWIK, C doesn't allow this:
if()
{
//some code
}
//some code
else{
//some code
}
The other issue being:
else if((isdigit(source[i]) )||(isalpha(source[i])). I would prefer it to be,
else if( (0 != isdigit(source[i])) || (0 != isalpha(source[i])) )
Or as suggested by Jonathan Leffler in a comment below: even better if you use if (isalnum(source[i])) since it checks for all alphanumeric.
Is it only me who finds the code not so readable?
Instead of if(op=='/'||op=='*'||op=='%'||op=='%') I would prefer
if((op == '/')||(op == '*')||(op == '%')) in terms of readability.
#include <stdio.h>
#include <stdlib.h>
static int top = 0;
static char stack[100];
void push(char thing2push)
{
if (top == 100){
fprintf(stderr, "Too many things in the stack");
exit(1);
}else{
stack[top] = thing2push;
top++;
}
}
then in the main I have:
extern void push(int);
push(1);
but that results in "segmentation fault". My guess that it has something to do with memory violations, but I have no idea on how to fix it.
EDIT Here's the full code:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
extern int pop();
extern void push(int);
void readTag(){
int tagVal = getchar();
int poppedVal;
if (getchar() == '/'){
poppedVal = pop();
if (poppedVal != tagVal){
printf("NOT Valid");
exit(1);
}
}else{
push(1);
}
}
int main(int argc, char * argv[])
{
int ch;
while ((ch = getchar()) != EOF) {
if (!(isalpha(ch) || ch == '<'))
continue;
readTag();
}
printf("Valid");
exit(0);
}
and here's the stack:
#include <stdio.h>
#include <stdlib.h>
static int top = 0;
static char stack[100];
int isEmpty()
{
return !(top);
}
char pop()
{
if (isEmpty()){
fprintf(stderr, "Stack is empty");
exit(1);
}
top--;
return stack[top+1];
}
void push(char thing2push)
{
if (top == 100){
fprintf(stderr, "Too many things in the stack");
exit(1);
}else{
stack[top] = thing2push;
top++;
}
}
The top variable always indicates the next entry in the stack (which obviously does not contain a valid element, as far as your program concerns). So you're not supposed to read the value at stack[top].
The segmentation fault occurs in function pop, when top reaches 100:
top--; // top == 99
return stack[top+1]; // return stack[100]
You should write into stack[top], but read from stack[top-1].
You can leave function push as is, and change only function pop:
top--;
return stack[top];
I tried to make a program that writes struct elements to binary file and then writes the unique elements from the first file to another binary file. I compiled it with gcc and it works very good, but with MinGW the program freezes when it tries to open and create the second file. Do you have any idea where is the problem?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct element{
char name[80];
int p;
}ELEM;
void clear_stdin()
{
char str[255];
fgets(str,255,stdin);
}
int create()
{
FILE *f;
int d=0;
int c;
int n=0;
ELEM s;
f=fopen("file.bin","wb");
if(f==NULL)
{
printf("create(): Could not open file.bin for read\n");
return;
}
do{
printf("Add elements to file?:\n1 - yes\n2 - no\n");
scanf("%d",&c);
if (c==1)
{
printf("Name=");
clear_stdin();
fgets(s.name,80,stdin);
printf("P=");
scanf("%d",&s.p);
fwrite(&s,sizeof(ELEM),1,f);
n++;
}
else
d=1;
} while(d==0);
fclose(f);
return n;
}
void show(int n)
{
FILE *f;
ELEM s;
int i=0;
if(n==0)
return;
f=fopen("file.bin","rb");
while(i<n)
{
fread(&s,sizeof(ELEM),1,f);
puts(s.name);
printf("\t%d\n",s.p);
i++;
}
fclose(f);
}
int add(int n)
{
FILE *f;
int d=0;
int c;
ELEM s;
f=fopen("file.bin","ab");
if(f==NULL)
{
printf("add(): Could not open file.bin for append\n");
return;
}
do{
printf("Add elements to file?:\n1 - yes\n2 - no\n");
scanf("%d",&c);
if (c==1)
{
printf("Name=");
clear_stdin();
fgets(s.name,80,stdin);
printf("P=");
scanf("%d",&s.p);
fwrite(&s,sizeof(ELEM),1,f);
n++;
}
else
d=1;
} while(d==0);
fclose(f);
return n;
}
void func(int n)
{
FILE *f,*g;
ELEM v[20],w;
int i=0,j,k,x=0,s,gn=0,test;
f=fopen("file.bin","rb");
g=fopen("aux.bin","wb");
if((g==NULL)||(f==NULL))
{
if(g==NULL)
printf("function() : Could not open aux.bin for write\n");
if(f==NULL)
printf("function() : Could not open file.bin for read\n");
return;
}
i=0;
while(i<n)
{
fread(&v[i],sizeof(ELEM),1,f);
i++;
}
for(j=0;j<n;j++)
{
for(k=j+1;k<n;k++)
{
if(v[j].p==v[k].p)
x=1;
}
if(x==0)
{
s=strcmp(v[j].name,v[k].name);
if(s!=0)
{
fwrite(&v[j],sizeof(ELEM),1,g);
fread(&w,sizeof(ELEM),1,g);
gn++;
}
}
x=0;
}
test=fclose(g);
if(test!=0)
printf("function() : failed to closed file g\n");
test=fclose(f);
if(test!=0)
printf("function() : failed to closed file f\n");
g=fopen("aux.bin","rb");
if(g==NULL)
{
printf("function() : Could not open aux.bin for read\n");
return;
}
if(gn==0)
return;
i=0;
while(i<gn)
{
fread(&w,sizeof(ELEM),1,g);
puts(w.name);
printf("\t%d\n",w.p);
i++;
}
fclose(g);
}
int main()
{
int k=0,r,n;
do{
printf("1 - create file\n2 - add elements to file\n3 - show elements\n4 - put unique elements in another file\n5 - exit program\n");
scanf("%d",&r);
switch(r)
{
case 1 : n=create(); break;
case 2 : n=add(n); break;
case 3 : show(n); break;
case 4 : func(n); break;
case 5 : k=1; break;
default : printf("Command unrecognized!\n");
}
} while(k==0);
return 0;
}
EDIT:
function func() is the only problem.
EDIT: Yes I can run it under gdb.
EDIT:
sizeof(ELEM)=84 offsetof(ELEM,p)=80 in both cases.
Wow guys you will not guess this: aux.bin, actually anything aux.* is a reserved filename on Windows! That's why it is taking forever! Take a look here so you dont accidentally choose another reserved filename:
windows file name specification (search the page for 'aux')