Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 从文件中读取文本,并在需要时重新定位_C - Fatal编程技术网

C 从文件中读取文本,并在需要时重新定位

C 从文件中读取文本,并在需要时重新定位,c,C,我想逐行读取文本文件中的文本,并对这些行进行处理。我可以做所有的处理,但我不能用mallocrealloc来增加内存。我首先给出了有限的内存,如果我的文本文件的行字符在这个限制内,一切都正常。如果我使用像每行10000个字符这样的大文件,它只能读取到我的极限。我不太明白如何使用realloc()。对此代码我能做些什么 void stat(char* fileptr) { FILE *fp; char *linebuffer; int line=0; int sum=0;

我想逐行读取文本文件中的文本,并对这些行进行处理。我可以做所有的处理,但我不能用mallocrealloc来增加内存。我首先给出了有限的内存,如果我的文本文件的行字符在这个限制内,一切都正常。如果我使用像每行10000个字符这样的大文件,它只能读取到我的极限。我不太明白如何使用
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);
}
void stat(char*fileptr)
{
文件*fp;
字符*行缓冲区;
内线=0;
整数和=0;
int max=0;
int min=0;
int maxlinelen=512;
int i=0,j=0;
int maxlen=512;
int curlinglen[maxlen];
linebuffer=(char*)malloc(maxlinelen*sizeof(char));
if(linebuffer==NULL)
{
printf(“为linebuffer分配内存时出错”);
出口(1);
}
如果((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(“为linebuffer重新分配空间时出错”);
出口(1);
}
}
line++;
sum=sum+strlen(行缓冲区);
curlinlen[i]=strlen(行缓冲区);
i++;
}
}
最小值=卷曲长度[0];
最大值=卷曲长度[0];
对于(j=0;j
在
linebuffer
中读取和存储最多
maxlinelen-1
个字符,然后0-终止它。因此

if(strlen(linebuffer)==maxlinelen)
从不满足,
strlen(linebuffer)
最多可以是
maxlinelen-1
。更改条件,您将看到如果文件包含长行,
maxlinelen
会增加(除非
realloc
失败)

但是,您当前的代码将把读入的部分行计算为整行,并将该行的下一块作为新行读取。若要增加缓冲区直到整行装入,您必须在收集行长度并增加行数之前继续读取文件。但我们必须检查是否有整行(包括末尾的换行符)是在
fgets
在扩大缓冲区之前读取最大允许数量的
char
s的情况下读取的,或者我们将以下行连接起来,并将两行(或在异常情况下甚至更多)作为一行计数

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
调用,效率相当低)方法。

您可以通过使用
fgetc
,做更多的编码工作,避免在潜在的大字符串上重复使用strlen。不过我不会挑剔,因为这一点都不好玩。谢谢Daniel!!但我仍然有问题。我的示例文本文件(infle)这样;它的正确输出;行数:2最大行长:50001最小行长:10001平均值:30001.00我的程序输出行数:8最大行长:25427最小行长:511平均值:7500,25我不明白。这有什么不对?@ccc那是因为你增加了行数
line++;
等等。ev如果
fgets
没有读入整行,请将
curlinlen
数组打印出来,直到填满为止。@danielfscher此文件变为2行。第一行变为10001 a,第二行变为50001 b。但是我的程序读取了8行??我在这里混淆了。我试着打印curlinlen数组,我得到了seg.fault。比如那,…..line++;sum=sum+strlen(linebuffer);curlinglen[i]=strlen(linebuffer);printf(“%s\n”,curlinglen[i]);//我也尝试过%c我得到了一些i++;@ccc首先,它从第一行读取511'a,然后重新分配并增加行数,将511存储在
curlinglen[0]中
。然后它从第一行读取下一个1023'a,将其预订为第二行,并增加缓冲区。然后下一个2047'a,仍然从文件的第一行读取为第3行,以此类推。
*sizeof(char)
是不需要的,并且键入返回
malloc()
是不明智的。而不是
sizeof(char)
我会使用
sizeof(*linebuffer)
,如果您决定将linebuffer的类型更改为宽字符串或其他类型,它会自动变大。
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);
  }