Reputation: 4007
I have written C program for Case Register. My program is working good. I used -Wall
for compile. It didn't show any Warning.But the problem is
, if I want to run it with bash loop
such as .test.sh | ./caseRegister
, the output is like the below:
:>>:1498.00
:>>:1499.00
:>>:1500.00
:>>:1501.00
:>>:1502.00
:>>:1503.00
:>>:1504.00
:>>:1505.00
:>>:1506.00
:>>:1507.00
:>>:1508.00
:>>:1509.00
:>>:1510.00
:>>:1511.00
:>>:1512.00
:>>:1513.00
:>>:1514.00
:>>:1515.00
:>>:1516.00
:>>:1517.00
:>>:1518.00
Segmentation fault
That test.sh is:
#/bin/sh
i=1
run=1
for ((; ; ))
do
echo $i
#echo $((i++))
done
Why my code is showing "segmentation Fault" for long run? Please anyone explain me the causes and prevention techniques to rectify it. Thank u in advance.
My Code is:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
struct prod_details
{
int no_prod;
double total;
double array[1024];
}pd;
char *getinput(char *inp)
{
printf(":");
gets(inp);
if(strlen(inp) > 11)
{
printf("Input is restricted to 10 character\n");
getinput(inp);
}
return inp;
}
void print()
{
printf("Grant Total is : %.2f\n",pd.total);
}
int check(char *str)
{
int i,minusflag=0,plusflag=0,optrflag=0;
if(strlen(str) == 0)
return 0;
if(str[strlen(str) -1] == '+' || str[strlen(str) -1] == '-' || str[strlen(str) -1] == '*')
{
printf("last operator\n");
return 1;
}
if(str[0] == '-')
{
i=1;
while(str[i] != '-' )
{
if(str[i] == '\0')
{
minusflag=1;
break;
}
i++;
}
if(str[i] == '-')
{
minusflag=0;
return 1;
}
}
if(str[0] == '-')
{
i=1;
while(str[i] != '+' )
{
if(str[i] == '\0')
{
minusflag=1;
break;
}
i++;
}
if(str[i] == '+')
{
minusflag=0;
return 1;
}
}
if(str[0] == '-' && minusflag == 1)
return 2;
if(str[0] == '+')
{
i=1;
while(str[i] != '+')
{
if(str[i] == '\0')
{
plusflag=1;
break;
}
i++;
}
if(str[i] == '+')
{
plusflag=0;
return 1;
}
}
if(str[0] == '+')
{
i=1;
while(str[i] != '-' )
{
if(str[i] == '\0')
{
plusflag=1;
break;
}
i++;
}
if(str[i] == '-')
{
plusflag=0;
return 1;
}
}
if(str[0] == '+' && plusflag == 1)
return 2;
if(str[0] == '*')
return 1;
if((str[0] == '+' || str[0] == '-') && (str[1] == '+' || str[1] == '-' || str[1] == '*' || str[1] == '/' ))
return 1;
for(i=0;i<strlen(str);i++)
{
if(((str[i] >= '!' && str[i] <= '/') || (str[i] >= ':' && str[i] <= '~')))
{
if(str[i] == '*' || str[i] == '+' || str[i] == '-' || str[i] == '/')
{
optrflag++;
}
else
return 1;
}
}
if(optrflag == 1)
return 3;
else if(optrflag > 1)
return 1;
return 2;
}
int expcalc(char *str)
{
char copy[10];
char op;
char *temp;
char numb[10],numf[10];
printf("Start of expcal\n");
int i;
double result=0;
for(i=0;i<strlen(str);i++)
{
if(str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/')
{
op = str[i];
}
}
strcpy(copy,str);
i=0;
while(str[i] != op)
{
numf[i] = str[i];
i++;
}
numf[i] ='\0';
temp=strchr(copy,op);
i=1;
printf("\n");
while(temp[i] != '\0')
{
numb[i-1] = temp[i];
i++;
}
numb[i-1] = '\0';
switch(op)
{
case '+':
result=atof(numf)+atof(numb);
break;
case '-':
result=atof(numf)-atof(numb);
break;
case '*':
result=atof(numf)*atof(numb);
break;
case '/':
result=atof(numf)/atof(numb);
break;
default:
break;
}
printf("%.2f\n",result);
if((pd.total+result) < 0)
{
printf("Couldn't calculate\n");
return 0;
}
pd.array[pd.no_prod]=result;
pd.total=pd.total+result;
printf(">>:%.2f\n",pd.total);
pd.no_prod++;
return 0;
}
int calc(char *str)
{
if((pd.total+atof(str)) < 0)
{
printf("Coundn't Calculate\n");
return 0;
}
pd.array[pd.no_prod]=atof(str);
pd.total=pd.total+pd.array[pd.no_prod];
printf(">>:%.2f\n",pd.total);
pd.no_prod++;
return 0;
}
int call()
{
int chkflg;
char input[1024];
getinput(input);
chkflg=check(input);
if(chkflg == 3)
{
expcalc(input);
call();
}
else if(chkflg == 2)
{
calc(input);
call();
}
else if(chkflg == 1)
{
printf("You have entered Wrogly!!!\n Please enter correctly\n");
call();
}
else
{
print();
return 1;
}
return 0;
}
int main()
{
printf("..CASE RIGISTER..\n");
call();
return 0;
}
Upvotes: 2
Views: 21852
Reputation: 6877
pd.array only has room for 1024 results. You have to check that no_prod is < 1024 before writing to it, otherwise you'll write in unallocated memory, which is what gives you a segmentation fault. Once no_prod reached 1024 you have to abort the program (I assume you haven't worked with dynamic allocation yet).
It's good practice to not actually write 1024 at the check though, but rather use a macro for the array size (don't worry about this if you haven't used macros either).
Upvotes: 1