从文件中读取文本并在需要时重新分配

ccc*_*ccc 5 c

我想从文本文件中逐行读取文本并对这些行进行一些处理。我可以完成所有处理,但无法使用 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);
}
Run Code Online (Sandbox Code Playgroud)

Dan*_*her 4

fgets(linebuffer,maxlinelen,fp)
Run Code Online (Sandbox Code Playgroud)

读取并存储最多maxlinelen - 1字符linebuffer并以 0 终止。因此

if(strlen(linebuffer)==maxlinelen)
Run Code Online (Sandbox Code Playgroud)

永远不会满足,strlen(linebuffer)最多只能满足maxlinelen - 1。更改条件,maxlinelen如果文件包含长行,您将看到增加(除非realloc失败)。

然而,您当前的代码会将读入的部分行计为整行,并将该行的下一个块读取为新行。要增大缓冲区直到容纳整行,您必须在收集行长度并增加行计数之前继续从文件中读取。但是我们必须检查是否读取了整行(包括末尾的换行符),以防在扩大缓冲区之前fgets读取最大允许数量的chars,或者我们将连接以下行并计数两个(或者在奇怪的情况下甚至更多) ) 行合而为一。

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);
  }
Run Code Online (Sandbox Code Playgroud)

将是一种(由于调用而效率相当低strlen)的方法。