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