0

I'm trying to keep the words from a file into an array but I only read the first 8.

My code below.

#define BUF 128 /* can change the buffer size as well */


char ** readFileContentArray(char* filename){

   int lines = 128;
   char **     strLines = (char **)malloc(sizeof(char*)*lines);
   FILE *plist = NULL;
   int i = 0;

   char line[4];

   plist = fopen(filename, "r");
   while(fgets(line, BUF, plist)) {

       if(i >= lines){
           strLines = (char **)realloc(strLines, (lines*2) * sizeof(char *));
           lines = lines*2;
       }

       strLines[i] = strdup(line);
       i++;
   }


   return strLines;
}

The file that I'm reading is formed like below:

aaaa

bbbb

cccc

dddd

eeee

ffff

gggg

hhhh

iiii

jjjj

jlopez
  • 6,287
  • 2
  • 51
  • 90

2 Answers2

3

You could pass pointers to two integers so the caller can tell how many items are allocated in the array.
Call as char **strArray = readFileContentArray ( "file.txt", &total, &used);
The results may be printed with

for ( i = 0; i < used; i++) {
    printf ( "%s", strArray[i]);
}

and similarly free'd.

for ( i = 0; i < used; i++) {
    free ( strArray[i]);
}
free ( strArry);

these would be used in the calling function.

char ** readFileContentArray(char* filename, int *lines, int *used){

    *lines = 128;
    *used = 0;
    char **strLines = malloc(sizeof(char*)*(*lines));
    char **strTemp = NULL;
    FILE *plist = NULL;

    char line[6];

    plist = fopen(filename, "r");
    if ( plist == NULL) {
        return NULL;
    }
    while(fgets(line, sizeof ( line), plist)) {
        if ( line[0] == '\n') {
            continue;//blank line
        }
        if(*used >= *lines){
            strTemp = realloc(strLines, ((*lines)*2) * sizeof(char *));
            if ( strTemp == NULL) {
                printf ( "realloc failed\n");
                return strLines;
            }
            strLines = strTemp;
            *lines = (*lines)*2;
        }
        strLines[*used] = strdup(line);
        *used += 1;
    }
    return strLines;
}
user3121023
  • 7,333
  • 5
  • 17
  • 14
2

Your code has several problems.

  1. Don't cast the result of malloc/calloc/realloc in C
  2. You don't check if fopen was successful. This can be done by checking its return value. fopen returns NULL on failure.
  3. You allow fgets to write 128 characters into line, which can at most hold 4 characters.

Fixed code:

#define BUF 128 /* Change to max size of a line */


char ** readFileContentArray(char* filename){

   int lines = 128;
   char **     strLines = malloc(sizeof(char*) * lines);

   if(strLines == NULL) //If malloc failed
       return NULL; 
   FILE *plist = NULL;
   int i = 0;

   char line[BUF]; //Allocate BUF size

   if((plist = fopen(filename, "r")) == NULL) //If fopen failed
       return NULL; 
   while(fgets(line, BUF, plist)) { 

       if(i >= lines){
           char* temp;
           if((temp = realloc(strLines, (lines*2) * sizeof(char *))) == NULL) //If realloc failed
           {
               free(strLines);
               return NULL;
           ]
           lines = lines*2;
       }

       strLines[i] = strdup(line);
       i++;
   }

   fclose(plist); //Close file after its use

   return realloc(strLines, i * sizeof(char*)); //Return correct size
}
Community
  • 1
  • 1
Spikatrix
  • 19,653
  • 7
  • 38
  • 77