我想逐行读取文本文件中的文本,并对这些行进行一些处理。我可以做所有处理,但我不能用malloc-realloc增长内存。我首先给了有限的内存,如果我的文本文件的行字符在这个限制内,一切都可以。如果我每行使用10,000个字符之类的大文件,它只会读到我的限制。我并不完全了解如何使用realloc()
。我该怎么办这个代码?
void stat(char* fileptr)
{
FILE *fp;
char *linebuffer;
int line=0;
int sum=0;
int max=0;
int min=0;
int maxlinelen=512;
int i=0,j=0;
int maxlen=512;
int curlinelen[maxlen];
linebuffer=(char*) malloc(maxlinelen * sizeof(char));
if(linebuffer==NULL)
{
printf("Error occurred allocating memory for linebuffer");
exit(1);
}
if((fp=fopen(fileptr,"r"))!=NULL)
{
while((fgets(linebuffer,maxlinelen,fp))!=NULL)
{
if(strlen(linebuffer)==maxlinelen)
{
maxlinelen*=2;
linebuffer=realloc(linebuffer,maxlinelen * sizeof(char));
if(linebuffer==NULL)
{
printf("Error occurred reallocating space for linebuffer");
exit(1);
}
}
line++;
sum=sum+strlen(linebuffer);
curlinelen[i]=strlen(linebuffer);
i++;
}
}
min=curlinelen[0];
max=curlinelen[0];
for(j=0;j<line;j++)
{
if(curlinelen[j]<min)
{
min=curlinelen[j];
}
if(curlinelen[j]>max)
{
max=curlinelen[j];
}
}
printf("No. of lines =%d\n",line);
printf("Maximum line length =%d\n",max);
printf("Minimum line length =%d\n",min);
printf("Average line length =%8.2f\n",(float)sum/(float)line);
fclose(fp);
}
答案 0 :(得分:3)
fgets(linebuffer,maxlinelen,fp)
在maxlinelen - 1
中读取并存储最多linebuffer
个字符,并以0结尾。因此
if(strlen(linebuffer)==maxlinelen)
永远不会满意,strlen(linebuffer)
最多可以maxlinelen - 1
。更改条件,如果文件包含长行,您将看到maxlinelen
增加(除非realloc
失败)。
然而,您当前的代码会将读取的部分行计为整行,并将该行的下一个行读作新行。要增大缓冲区直到整条线都适合,必须先从文件中读取,然后再收集行长并增加行数。但是我们必须检查是否在扩展缓冲区之前fgets
读取char
的最大允许数量时读取了整行(包括最后的换行符),或者我们连接了以下行并计算两个(或者更奇怪的情况下)一行。
while((fgets(linebuffer,maxlinelen,fp))!=NULL)
{
while((strlen(linebuffer) == maxlinelen-1) && (linebuffer[maxlinelen-2] != '\n'))
{
maxlinelen*=2;
linebuffer=realloc(linebuffer,maxlinelen * sizeof(char));
if(linebuffer==NULL)
{
printf("Error occurred reallocating space for linebuffer");
exit(1);
}
fgets(linebuffer + (maxlinelen/2 - 1), maxlinelen/2 + 1, fp);
}
将是一种(相当低效,由于strlen
调用)的方式来做到这一点。