我正在尝试使用动态内存分配从文件中删除多余的空格和换行符,但出现内存分段错误。
#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 filen");
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 createn");
return;
}
i=0;
while((fputc(p[i],fp))!=EOF)
{
i++;
}
fclose(fp);
}
对于上述程序,我得到了分段错误(核心转储),如果我使用 strlen(p+i+2) 修改 memmove 指令,那么它不会给出分段错误,而是陷入某种无限循环。请告诉我哪里出错了。
您的文件读取已损坏; EOF
不是角色,因此您无法将角色与它进行比较并获得正确的结果。
改为使用 fread()
读取整个文件。请注意,它可能会返回较短的长度,并且无论如何都需要循环。
也停止使用 strlen()
;你知道从你分配缓冲区和读取文件开始的长度,所以像你一样一直使用 strlen()
在性能方面是非常浪费的。
不要将 char 与 EOF 进行比较,EOF 是 int。
memmove的整个想法很容易出错,为什么不在阅读时检查字节:
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;
}
根本不需要任何内存。