0

So I'm working on a function that will use fgetc to read a line into a buffer. so I can use that buffer as I please, and then refill the buffer with the next line. My function works however I have to repeat code outside of the for loop to process the last line as shown here:

for(i = 0, c = 1; ch != EOF; i++)
{
    ch = fgetc(grab);
    if(ch == 0x0A)
    {
        /*Process Line*/
        c = 1;
    }
    else 
    {
        linetmp = realloc(line, (c + 1) * sizeof(char));
        if(!linetmp)
        {
            free(line);
            free(url);
            printf("\nError! Memory allocation failed!");
            return 1;
        }
        line = linetmp;
        line[c - 1] = ch;
        line[c] = 0x00;
        c++;
    }
}
/*repeat if(ch == 0x0A) statement*/

I would rather do this all in the same loop but am not sure on how I would go about doing this. Any help would be greatly appreciated!

Keith Miller
  • 1,337
  • 1
  • 16
  • 32

2 Answers2

1

I would recommend that you instead use getline() if you're on a POSIX system.

Also, your logic is strange since you check for EOF in the loop header only, but update ch inside the loop. That means it will run through with ch == EOF, before the loop condition is re-evaluated.

You should try putting the updating and the check together, making the loop header read like this:

for(i = 0, c = 1; (ch = fgetc()) != EOF; i++)

Also, you need to think about line separators, both '\n' (carriage return) and '\n' (line feed) can occur.

unwind
  • 391,730
  • 64
  • 469
  • 606
0

I don't think you should reallocate after each character. If you want to have the buffer at the smallest value needed, you could reallocate at the end with ( strlen() + 1); Also, there is a function fgets() which reads a line.

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>


int somefunc(FILE *grab)
{
   int current_size = 100;
   int data_size = current_size - 1;
   char *url = malloc(current_size);
   char *line = malloc(current_size);
   char *linetmp;
   int ch;
   ch = fgetc(grab);
   int i = 0;
   int c  = 0;
   while (ch  != EOF && ch != 0x0A )
   {
      i++;
      if ( i > data_size )
      {
         current_size = current_size * 2;
         data_size = current_size - 1;
         linetmp = realloc(line, current_size);
         if (!linetmp)
         {
            free(line);
            free(url);
            printf("\nError! Memory allocation failed!");
            return 1;
         }
         line = linetmp;
      }
      line[c] = ch;
      c++;
      ch = fgetc(grab);
   }
   line[c] = '\0';
   linetmp = realloc(line,strlen(line) + 1);
   line = linetmp;
   printf("we just read line->%s\n",line);
   free(line);
   free(url);
   return 0;
}


int main(void)
{
   char *cpFilename = "somefile.txt";
   FILE *fp = fopen(cpFilename,"r");
   if ( fp == NULL )
   {
      printf("ERROR: could not open %s\n",cpFilename);
      printf("Error code: %d\n",errno);
      perror("ERROR:");
      return 1;
   }
   int return_code = somefunc(fp);
   while (return_code != EOF && return_code != 1)
   {
      return_code = somefunc(fp);
   }
   fclose(fp);
}
Scooter
  • 6,802
  • 8
  • 41
  • 64