#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];
Related
why when attempt to use function N I get a Segmentation fault 11 .. im new to malloc so i dont exactly know where to look for my error .. im trying to read from a file and put certain line through fscanf to my double array ..
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
void V(int *id,int i,int *praca, double *plat,int *datum, FILE **f)
{
char meno[2000],priezvisko[2000];
if ((*f = fopen("zam.txt", "r")) == NULL)
{
printf("Neda sa otvorit");
// koniec programu
return ;
}
while(//vypis informacii zamestnancov
fscanf(*f,"%d %s %s %d %lf %d",&id[i],&meno[i],&priezvisko[i],&praca[i],&plat[i],&datum[i])>0)
{
printf(" osobne cislo zamestnanca:%d\n meno priezvisko:%s %s\n administrativa/vyrobny pracovnik:%d\n plat:%g\n datum:%08d\n\n",id[i],&meno[i],&priezvisko[i],praca[i],plat[i],datum[i]);
i++;
}
}
void N(int i,double **platy, FILE *f)
{
rewind(f);
int j=0,k=0;
char line[1800];
int suma = 0;
int count = 0;
int lineNumber = 2;
double val;
double d;
while(fgets(line, sizeof(line), f)!= NULL)
{
if (count == lineNumber)
{
suma++; //pocet platov
count++;
lineNumber+=6;
*platy=malloc(suma*sizeof(double));
fscanf (f, "%lf", platy[i]);
i++;
}
else
{
count++;
}
}
printf("SUMA: %d",suma);
}
int main() //MAIN
{
int i=0,id[1800],praca[1800],datum[1800];
char *meno[1800],*priezvisko[1800],z;
double plat[1800],*platy;
FILE *f;
while((z = getchar())!='K')
{
if(z == 'V')
V(id,i,praca,plat,datum,&f);
if(z == 'P')
P(i,praca,plat,datum,f);
if(z == 'N')
N(i,&platy,f);
}
/*
for (j=0 ; j<suma; j++) {
printf("%g\n",*platy[j]);
}
*/
return 0;
}
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);
}
}
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.
So i keep getting the message invalid expression "..." Bus Error (core dumped)if i type ./rpcalc "..." also if i just type in the command line ./rpcalc 1 i get the Segmentation Fault(core dumped) message. This is my entire code i would appreciate any help.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define max 10
#define NUMBER 'n'
int main(int argc, char *argv[])
{
double tmp;
char c;
if(argc <= 1) {
fprintf(stderr,"invalid call\n");
return 1;
}
while(--argc)
{
c = getop(*++argv);
switch(c)
{
case NUMBER:
push(atof(*argv));
break;
case '+':
push(pop() + pop());
break;
case '-':
tmp = pop();
push(pop() - tmp);
break;
case '*':
push(pop() * pop());
break;
case '/':
tmp = pop();
if(!tmp){
printf("can't divide by 0\n");
}
else{
push(pop()/tmp);
}
break;
default:
printf("invalid expression %s\n", *argv);
}
}
printf("%g\n",pop());
return 0;
}
int push (int stack[max], int *top, int *data)
{
if(*top == max -1)
return(-1);
else
{
*top = *top +1;
stack[*top] = *data;
return(1);
}
}
int pop(int stack[max], int *top, int *data)
{
if(*top == -1)
return(-1);
else
{
*data = stack[*top];
*top = *top - 1;
return(1);
}
}
static int isNumber(const char *s){
if(*s == '-' || *s == '+') s++;
if(*s == '\0'){
return 0;
}
while (isdigit(*s)) s++;
if(*s == 'e' || *s == 'E'){
s++;
while(isdigit(*s)) s++;
}
return *s == '\0';
}
int getop(const char *op){
return isNumber(op) ? NUMBER : *op;
}
gcc -Wall -ansi -pedantic
First, you probably shouldn't be returning a static int. Return either a char or an int or unsigned int.
Next: You're invoking functions with incorrect parameters:
Line 28:
push(atof(*argv));
This is not how you've defined your function.
int push (int stack[max], int *top, int *data);
It requires an array of stack[max], an int pointer, and another int pointer
Passing in a float is not correct.
Actually it looks almost like all of your function calls are with incorrect parameters.
I've looked through similar questions on stackoverflow, but I'm still not sure how to fix it.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
extern char * pop();
extern void push(char *);
int i;
int j=0;
//Resize the array to 1.1 it's size
void reSize(char* tag){
char *temp = malloc(1.1*sizeof(tag));
for (i=0;i<(sizeof(tag)/sizeof(tag[0]));i++){
*(temp+i) = *(tag+i);
}
free(tag);
tag = temp;
}
int compare(char* tag, char* popVal){
i=0;
while (i<sizeof(tag)/sizeof(tag[0])){
if (*(tag+i) == *(popVal+i)){
i++;
}else{
return 0;
}
}
return 1;
}
void dothis(){
int ch;
int n=0;
char *tag = malloc(10* sizeof(char));
char *popVal;
while ((ch = getchar()) != '>'){
tag[n] = ch;
n++;
if (n > (sizeof(tag)/sizeof(tag[0]))-1 ){
reSize(tag);
}
}
if (*tag == '/'){
popVal = malloc(sizeof(tag));
popVal = pop();
j--;
if (!(compare(tag,popVal))){ // Compare will return 1 if the same
printf("Invalid");
exit(1);
}
}else{
push(tag);
j++;
}
free(tag);
free(popVal);
}
int main(int argc, char * argv[])
{
int ch;
while ((ch = getchar()) != EOF) {
if (!(isalpha(ch) || ch == '<'))
continue;
dothis();
}
if (j != 0){
printf("Invalid\n");
exit(1);
}
printf("Valid\n");
exit(0);
}
then the external methods:
#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 (char *) stack[top];
}
void push(char * thing2push)
{
if (top == 100){
fprintf(stderr, "Too many things in the stack");
exit(1);
}else{
stack[top] = thing2push;
top++;
}
}
In a previous question, the selected answer was "passing a pointer to memory you haven't allocated with malloc will definitely not do good things.", but I"m pretty sure I allocated everything
Here's a bug:
popVal = malloc(sizeof(tag));
popVal = pop();
You malloc an area and then immediately lose that value, replacing it with something from pop().
This is most definitely a bug:
while ((ch = getchar()) != '>'){
tag[n] = ch;
n++;
if (n > (sizeof(tag)/sizeof(tag[0]))-1 ){
You assign to tag[n] before checking the range of n. When you do check the range of n after the fact you use sizeof(tag). tag is a pointer. It's size is 4 (32 bit) or 8 (64 bit). Neither size has anything to do with how big n can be before tag[n] writes into invalid memory.
Another bug:
char * pop()
{
if (isEmpty()){
fprintf(stderr, "Stack is empty");
exit(1);
}
top--;
return (char *) stack[top];
}
If you're a beginning C programmer, never cast a pointer. Because I doubt that you have learned enough yet to know if this is a good or bad idea.
The type system exists for good reasons and if it complains about some types not matching, it is far more likely to be right than you are.