Zuzana - 7 months ago 77
C Question

# Segmentation fault in C while using getchar()

I am writing a program that can read letters and it gives to them values

`2^n`
, so
`a=2^0`
,
`b=2^1`
....
`z=2^25`
and then I sum them. Somewhere in the input must be
`|`
and I count letters before and letter after it separately -
`sum[0]=`
before
`|`
,
`sum[1]=`
after
`|`
. When I type
`aeoifha|shzs`
, everything is OK, but when I type
`|abc`
or
`abc|`
, it gives me Segmentation fault, but I need it to tell me it is
`sum[0]=0`
and
`sum[1]=7`
for
`|abc`
or
`sum[0]=7`
and
`sum[1]=0`
for
`abc|`
. If there is just
`|`
, it is Wrong. The output is really Wrong, but it also gives me Segmentation fault.

Here is the code:

``````const int table[] = {1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432};
const char *a_z = "abcdefghijklmnopqrstuvwxyz";
long long int sum[2] = {0};
int ch, count = 0;

for(;;)
{
if(!islower(ch = getchar()))
{
if(ch == '\n' && sum[0] && sum[1])
break;
else if(ch == EOF)
{
printf("Wrong.\n");
}
else if(ch == '|' && sum[0] != 0 && count == 0)
{
count = 1;
continue;
}
printf("Wrong.\n");
sum[0] = sum[1] = count = 0;
while(ch != '\n' && (ch=getchar())!=EOF && ch != '\n')
continue;
}
sum[count] += table[strchr(a_z, ch) - a_z];
}
``````

Any idea how to get rid of the fault and how to give sum[]=0?

Before updating the `sum[count]`, you don't have checked if the `strchr(a_z, ch)` is not NULL, meaning that `ch` is not an expected `'a'...'z'` character.

After entering `"abc|"` and pressing 'Return' key, an additional `'\n' = 0x0A` is parsed but not filtered by `if(ch == '\n' && sum[0] && sum[1]) break;` because `sum[1]` is equal to `0`.

First modification: (Stop even when left or right is missing)

But, to prevent a missing `'|'`, the break-condition shall be true only when `count = 1` (equal `'|'` detection).

``````    if(!islower(ch = getchar()))
{
if(ch == '\n' && (sum[0] || sum[1]) && (count == 1))
``````

``````    if(!islower(ch = getchar()))
{
if(ch == '\n' && sum[0] && sum[1])
``````

Second modification (force to switch to count=1 even left is missing):

``````        else if(ch == '|' && count == 0)
{
count = 1;
``````

``````        else if(ch == '|' && sum[0] != 0 && count == 0)
And to prevent unexpected `ch` value, filter before:
``````    if (strchr(a_z, ch)!=NULL) { // only 'a' to 'z' characters