Reputation: 53
I am trying to remove extra spaces and newlines from a file using dynaminc memory allocation but I get memory segmentation fault.
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main(int argc,char **argv)
{
FILE*fp;
char ch;
char *p;
int i=0,size;
if((fp = fopen(argv[1],"r"))==NULL)
{
printf("Couldnt open file\n");
return;
}
fseek(fp,0,2);
size=ftell(fp);
p = calloc(1,size+1);
rewind(fp);
while((p[i] = fgetc(fp))!=EOF)
{
i++;
}
p[i]=EOF;
fclose(fp);
for ( i=0; p[i]!=EOF; i++)
{
if (p[i] == ' ' && p[i+1] == ' ')
{
memmove(p+i,p+i+1,strlen(p+i+1));
i--;
}
if (p[i] == '\n' && p[i+1] == '\n')
{
memmove(p+i,p+i+1,strlen(p+i+1));
i--;
}
} //all extra spaces and newlines deleted..
fp = fopen("modified","w");
if (fp==NULL)
{
printf("coudlnt create\n");
return;
}
i=0;
while((fputc(p[i],fp))!=EOF)
{
i++;
}
fclose(fp);
}
I get segmentation fault(core dumped) for the above program and if I modify the memmove instruction with strlen(p+i+2) then it doesnt give segmentation fault but gets stuck in some sort of infinite loop.Please tell me where I am going wrong.
Upvotes: 0
Views: 663
Reputation: 3325
Do not compare char with EOF, which is int.
The whole idea with memmove is error prone, why not check bytes when you are reading it:
int b; // should be int
while ((b = fgetc(fp)) != EOF) {
char c = (char)b;
if (p[i] == ' ' && c== ' ') // the same for '\n'
continue;
p[++i] = c;
}
No need in any memmove at all.
Upvotes: 1
Reputation: 399703
Your file-reading is broken; EOF
is not a character so you cannot compare a character against it and get the proper result.
Read the entire file instead, using fread()
. Note that it might return a shorter length and need to be looped anyway.
Also stop using strlen()
; you know the length from when you allocated the buffer and read the file in, so it's extremely wasteful in terms of performance to use strlen()
all the time like you do.
Upvotes: 1