Reading text from a file and redistributing if necessary

I want to read text from a text file line by line and do some processing on those lines. I can do all the processing, but I cannot develop the memory using malloc-realloc. At first I gave limited memory if my lines in text files are in this limit, everything is in order. If I use large files, for example, 10,000 characters per line, they are read only to my limit. I do not quite understand how to use realloc() . what can i do with this code?

  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); } 
+4
source share
2 answers
 fgets(linebuffer,maxlinelen,fp) 

reads and saves no more than maxlinelen - 1 characters in linebuffer and 0-completes it. In this way,

 if(strlen(linebuffer)==maxlinelen) 

never executed, strlen(linebuffer) can be no more than maxlinelen - 1 . Change the condition and you will see that maxlinelen incremented if the file contains long lines (unless realloc is working).

Your current code, however, will count the partial line read as a whole line and read the next fragment of the line as a new line. To increase the buffer until the entire line has been entered, you must continue reading from the file before collecting the line length and increasing the number of lines. But we need to check whether the full line has been read (including the new line at the end), in case fgets reads the maximum char number before the buffer extension, or we will concatenate the next line and count two (or in fictitious cases even more) lines as one.

 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); } 

would be (rather inefficient due to strlen calls) for this.

+3
source

This is my realloc () file, readable line by line.

 void ReadDataFile() { FILE *fi = NULL; int i = 0; char *szString = 0; nLine = 0; char **g_chArr; char **strTmp; char szTmp[200]; char g_szDebug[1024]; fi = fopen("test.txt", "r"); if(!feof(fi)) { sprintf_s(g_szDebug, "%s\n", "Start Reading File..."); OutputDebugString(g_szDebug); } g_chArr = (char **)calloc(1, sizeof(char *)); while(!feof(fi)) { strTmp = (char **)realloc(g_chArr, sizeof(char *)*(nLine+1)); if(strTmp != NULL) { g_chArr = strTmp; } g_chArr[nLine] = strdup(fgets(szTmp, sizeof(szTmp), fi)); nLine++; } fclose(fi); for(i=0; i<nLine; ++i) { free(g_chArr[i]); } free(g_chArr); } 
-1
source

Source: https://habr.com/ru/post/1445554/


All Articles