0

I want read a simple file line by line and save the content into an array. If I compile the source code I get this error:

test.C: In function ‘char* read_file(int, int, const char*)’:
test.C:14:11: error: cannot convert ‘char (*)[1024]’ to ‘char*’ in return
    return words;
           ^

What does it means? Why can I not return a pointer of an 2D-Array? Here is the source code.

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

char * read_file(int buf, int size, const char *fname){
   char words[size][buf];
   FILE *fptr = NULL; 
   int idx = 0;

   fptr = fopen(fname, "r");
   while(fgets(words[idx], buf, fptr)) {
      words[idx][strlen(words[idx]) - 1] = '\0';
      idx++;
   }
   return words;
}

int main(void) {
   char * words;
   words = read_file(1024, 100, "text.txt");
   int i;
   for(i = 0; i < 100; ++i)
        printf("%s\n", words[i]);
}
Sam
  • 387
  • 2
  • 9
  • 22

1 Answers1

6

You actually have two problems: The first one is about the error. An array of array of char is not the same as a pointer to char. As arrays decays to pointers, an array of arrays of char is equivalent to a pointer to array of char, or char (*)[buf] in your specific case.

The second problem is worse, and that is you try to return a pointer to a local variable. Local variables go out of scope once the function returns, and basically cease to exist. So once the function returns the pointer is no longer valid.

Since you use variable-length arrays, one solution you have is to allocate the arrays dynamically, as a pointer to pointer to char, i.e. char **, and return that. Another solution is to pass the array as an argument.


Simplest solution, in my opinion, declare the array in the main function and pass it to the function, that way you don't have to bother with pointers and dynamic allocation, and more specifically with freeing the memory later.

Something like this:

#define STRING_COUNT  100    // Number of strings
#define STRING_SIZE   1024   // Size of each string

// Open and read the file, returns the number of "words" read
size_t read_file(const char *filename, char (*words)[STRING_SIZE])
{
    // Implement the function...
    // Don't forget to return the number of "words", actually lines, you read
}

int main(void)
{
    char words[STRING_COUNT][STRING_SIZE];
    size_t number_words = read_file("test.txt", words);

    // Use the "words" here...
    ...

    return 0;
}
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621